I am trying to convert a GMT time which is stored as epoch into CST.
Below is the current code I am running in java.
if (originalRFC.get("sysmodtime")!=null){
var sysmod = originalRFC.get("sysmodtime"); // Hold the sysmodtime value in a variable
logger.debug('Sysmodtime Before: ' + sysmod); // Output to log before before converstion to CST - (in GMT)
var format = new java.text.SimpleDateFormat("MMMM d, yyyy HH:mm:ss a z"); // Format the string will be in
var dateString = sysmod.toLocaleString(); // Convert the epoch to the string equivalent in CST
var parsedDate = format.parse(dateString); // Convert that CST String back to epoch
var sysmodConvert = parsedDate.getTime(); // Convert it to time and milliseconds
logger.debug('Sysmodtime After: ' + sysmodConvert); //Output to log after conversion to CST
genericRFC.setField("last-update-time",sysmodConvert);
}
See the below errors that are returned in the log, we can see the time before"1301382996000", and it breaks when I try to convert:
2011-05-02 14:25:49,926 [http-8080-1] sm702-adapter_convert script - Sysmodtime Before: 1301382996000
2011-05-02 14:25:49,941 [http-8080-1] sm702-adapter_convert script - Error while calling function convert
org.apache.bsf.BSFException: JavaScript Error: java.text.ParseException: Unparseable date: "[object JavaObject]"
Presuming by "epoch" you mean a UNIX timestamp (seconds since the UNIX epoch), this time format is timezone-agnostic. That is, your timestamp is not UTC, GMT, CST or any other timezone. It's just a number of seconds.
You apply timezones when you re-format the timestamp as something human-readable. In this case, just load it into a Date object, and your local timezone should be used.
For starters, toLocaleString() is Locale dependent and might be different than the format you have used (it is actually beyond your control).
Sencondly, if you know the CST time zone offset, you can always use getTime() add the offset and use setTime() to get this converted.
In Java world there is something like java.util.TimeZone that can give you right offset (use getOffset()) in milliseconds already.
Related
I am using moment.js, and I want to convert from ISO Format date time to UTC time zone.
I can convert from local time to UTC+ISOformat, but I am not able to convert ISO format to UTC time zone.
Input:
2018-03-22T00:00:00Z
Expected output:
date should be in UTC time zone. If I calculate the it should be:
22018-03-21T18:30:00Z
First I want to convert into ISO, After that convert into UTC**.
Not able to Converted local date time to ISO then UTC
We can convert into string, But from ISO format can convert or not?
Fox example: I want to convert ISODATE(2018-03-22T00:00:00Z) into UTC time zone.
function toISO(dt) {
return moment(dt).format("YYYY-MM-DDTHH:mm:ss") + "Z";
}
var date = new Date();
var isoDate= toISO(date)
Direct we can convert
function toISOWithUtc(dt) {
return moment(dt).utc().format("YYYY-MM-DDTHH:mm:ss") + "Z";
}
var date = new Date();
toISO(date)
Both 2018-03-22T00:00:00Z and 2018-03-21T18:30:00Z already are in UTC.
Note the Z in the end? This means that the date is in UTC. It's not a hardcoded letter that you can just append to the end - it has a specific meaning, it tells that the date/time is in UTC.
If you want to convert that UTC date to another timezone (I'm guessing that's what you want), you can use moment.tz:
// convert UTC 2018-03-22T00:00:00Z to Asia/Kolkata timezone
moment.tz('2018-03-22T00:00:00Z','Asia/Kolkata')
Just change the timezone name to the one you want to convert.
And calling format() will give you the converted date/time in ISO8601 format:
moment.tz('2018-03-22T00:00:00Z','Asia/Kolkata').format() // 2018-03-22T05:30:00+05:30
Note that the offset changed from Z to +05:30. This means that the date/time above is 5 hours and 30 minutes ahead UTC, which is the result of converting 2018-03-22T00:00:00Z to Kolkata's timezone.
Note: I think you're mistaking the concepts here.
UTC is a time standard. It defines things like the current date/time accross the world, it uses atomic clocks to make sure everybody on Earth are synchronized, and timezones are all based on offsets from UTC.
ISO8601 is a standard for exchanging date/time-related data. It defines formats (text representations of dates). A date/time can be in ISO format, regardless of being in UTC or not.
That's why "convert from UTC to ISO" (or vice-versa) makes no sense at all.
I'm located in PST timezone and I want to be able to take the string "2014-01-01" and convert it into Unix time without "2014-01-01" getting converted to PST.
Here's what I'm doing:
Date.parse(new Date("2014-01-01"))
I'm getting the value 1388534400000 which is equivalent to Tue Dec 31 2013 16:00:00 GMT-0800 (Pacific Standard Time)
I want to take the date as "2014-01-01" and not convert it into PST before converting it into Unix time.
A few things:
The Date constructor returns a Date object, not a string. You shouldn't wrap it in a call to Date.parse.
If you want a unix timestamp, just call getTime().
var ts = new Date("2014-01-01").getTime();
Alternatively, you can parse the date string without creating a Date object at all.
var ts = Date.parse("2014-01-01");
The behavior of date parsing in JavaScript is implementation dependent. Most browsers will already interpret a yyyy-mm-dd string to be in UTC, due to the dashes (-). If you replace with with slashes (/), you'll see the string get interpreted as local time instead.
I think you're confused about the output. You said the timestamp was equivalent to PST, but that's just one representation. It's also equivalent to the UTC value you passed in. It's not getting converted in the input, it's being converted when you are converting the timestamp back to local time.
You can use a library like moment.js, which gives you full control of the input and output. This is usually the best option, but has the overhead of including a library in your application.
Another way to convert the specified date string to Unix time is as follows:
var str = "2014-01-01";
var parts = str.split('-');
parts[1] -= 1; // js numeric mos are 0-11
var ms = Date.UTC( parts[0], parts[1], parts[2] ); // parts: YYYY, MM, DD
var unix_time = ms/1000; // Unix time uses seconds
console.log("Unix time: " + unix_time);
Date.UTC() returns the number of milliseconds occurring since January 1, 1970 midnight up to the instant of the specified date, irrespective of any timezone. The script transforms the result into Unix time, i.e. seconds, by dividing the number of milliseconds by 1000.
After splitting the string into an array, the code adjusts the element containing the month, lest JavaScript mistake its value for March; JavaScript comprehends numeric months as ranging from 0-11, not 1-12. Next, the script passes the elements sequentially in accordance with the year, month, day parameters that Date.UTC requires. Although UTC() expects numbers for parameters, it accepts the numerical strings.
Note: if you first create a new date object and expect to use a UTC method -- that results in an error because it is a static method of JavaScript's Date Object.
You may check the validity of the UTC() return value, using the aforementioned variables ms and str, as follows:
console.log( new Date( str ).toUTCString( ms ));
The output: Wed, 01 Jan 2014 00:00:00 GMT
See live demo here)
Passing a date string to the Date constructor instead of the numerical parameters it expects affords an unexpected benefit; the date string is treated as if it's timezone is UTC, i.e. zero by the local date object. Once created, the local date object executes its toUTCString() method to attain the above-indicated result. The toString() method would also yield the same output, but it appends local timezone information.
I'm trying to convert a date string to epoch, then epoch back to the date string to verify that I'm providing the correct date string.
var epoch = moment("10/15/2014 9:00").unix(); // do I need to do .local()?
var momentDate = moment(epoch); // I've also tried moment.utc(epoch)
var momentDateStr = momentDate.calendar();
alert("Values are: epoch = " + epoch + ", momentDateStr = " + momentDateStr);
Renders
Values are: epoch = 1413378000, momentDateStr = 01/17/1970
Note: I'm using the following version of the moment js script, //cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment-with-locales.js
There are a few things wrong here:
First, terminology. "Epoch" refers to the starting point of something. The "Unix Epoch" is Midnight, January 1st 1970 UTC. You can't convert an arbitrary "date string to epoch". You probably meant "Unix Time", which is often erroneously called "Epoch Time".
.unix() returns Unix Time in whole seconds, but the default moment constructor accepts a timestamp in milliseconds. You should instead use .valueOf() to return milliseconds. Note that calling .unix()*1000 would also work, but it would result in a loss of precision.
You're parsing a string without providing a format specifier. That isn't a good idea, as values like 1/2/2014 could be interpreted as either February 1st or as January 2nd, depending on the locale of where the code is running. (This is also why you get the deprecation warning in the console.) Instead, provide a format string that matches the expected input, such as:
moment("10/15/2014 9:00", "M/D/YYYY H:mm")
.calendar() has a very specific use. If you are near to the date, it will return a value like "Today 9:00 AM". If that's not what you expected, you should use the .format() function instead. Again, you may want to pass a format specifier.
To answer your questions in comments, No - you don't need to call .local() or .utc().
Putting it all together:
var ts = moment("10/15/2014 9:00", "M/D/YYYY H:mm").valueOf();
var m = moment(ts);
var s = m.format("M/D/YYYY H:mm");
alert("Values are: ts = " + ts + ", s = " + s);
On my machine, in the US Pacific time zone, it results in:
Values are: ts = 1413388800000, s = 10/15/2014 9:00
Since the input value is interpreted in terms of local time, you will get a different value for ts if you are in a different time zone.
Also note that if you really do want to work with whole seconds (possibly losing precision), moment has methods for that as well. You would use .unix() to return the timestamp in whole seconds, and moment.unix(ts) to parse it back to a moment.
var ts = moment("10/15/2014 9:00", "M/D/YYYY H:mm").unix();
var m = moment.unix(ts);
http://momentjs.com/docs/#/displaying/unix-timestamp/
You get the number of unix seconds, not milliseconds!
You you need to multiply it with 1000 or using valueOf() and don't forget to use a formatter, since you are using a non ISO 8601 format. And if you forget to pass the formatter, the date will be parsed in the UTC timezone or as an invalid date.
moment("10/15/2014 9:00", "MM/DD/YYYY HH:mm").valueOf()
Let's assume I know this time (hh:mm:ss) without date but I know it is today:
12:34:56
And I know the time is in CST timezone (UTC +0800). I need to get timestamp from the time.
Let's assume current UTC time is 2014/08/25 17:10:00 and CST is 2014/08/26 01:10:00 (UTC +0800) so it means in CST is already the next day. Therefore I can't use something like this:
var d = new Date().toJSON().slice(0,10);
// "d" returns "2014-08-25" in local time -> this is bad
I need to convert this:
1:10 (CST) --> to 2014/08/25 17:10 (UTC) or its timestamp 1408986600
How can I get full date-time or timestamp when I know the time and timezone only?
You can always manipulate the properties of a Date object directly:
var date = new Date();
date.setHours(5);
date.setMinutes(12);
date.setSeconds(10);
console.log(date.toUTCString());
I think I found the easy way using moment-timezone.js:
// hh:mm:ss in CST timezone
var cst_time = '1:10:00';
// get today's date in CST timezone
var cst_today = moment.tz("Asia/Shanghai").format("YYYY-MM-DD");
// convert date and time from CST to UTC and format it
var timestamp = moment(cst_today + " " + cst_time + " +0800").utc().format("YYYY/MM/DD HH:mm:ss");
// returns "2014/08/25 17:10:00" and it is correct
console.log(timestamp);
I have a ISO date string as below
var startTimeISOString = "2013-03-10T02:00:00Z";
when I convert it to date object in javascript using below code, it returns
var startTimeDate = new Date(startTimeISOString);
output is
Date {Sun Mar 10 2013 07:30:00 GMT+0530 (India Standard Time)}
It sure converts the ISOString to date but it converts to local time since new Date() is client dependent. How to just convert iso date time string to date and time but not to local date-time..?
Thanks
According to MDN:
Differences in assumed time zone
Given a date string of "March 7, 2014", parse() assumes a local time
zone, but given an ISO format such as "2014-03-07" it will assume a
time zone of UTC. Therefore Date objects produced using those strings
will represent different moments in time unless the system is set with
a local time zone of UTC. This means that two date strings that appear
equivalent may result in two different values depending on the format
of the string that is being converted (this behavior is changed in
ECMAScript ed 6 so that both will be treated as local).
I have done like this and am now getting the exact time which is inside the ISO date string instead of the local time
var startTimeISOString = "2013-03-10T02:00:00Z";
var startTime = new Date(startTimeISOString );
startTime = new Date( startTime.getTime() + ( startTime.getTimezoneOffset() * 60000 ) );
This will give the same date time inside iso date string , the output here is
o/p
Date {Sun Mar 10 2013 02:00:00 GMT+0530 (India Standard Time)}
To sum up the conversation from tracevipin's post:
All Date objects are based on a time value that is milliseconds since 1970-01-01T00:00:00Z so they are UTC at their core. This is different to UNIX, which uses a value that is represents seconds since the same epoch.
The Date.prototype.toString method returns an implementation dependent string that represents the time based on the system settings and timezone offset of the client (aka local time).
If a UTC ISO8601 time string is required, the Date.prototype.toISOString method can be used. It's quite easy to write a "shim" for this methods if required.
Lastly, do not trust Date.parse to parse a string. Support for an ISO8601 format UTC string is specified in ES5, however it's not consistently implemented across browsers in use. It is much better to parse the string manually (it's not hard, there are examples on SO of how to do it) if wide browser support is required (e.g. typical web application).
Simple ISO8601 UTC time stamp parser:
function dateObjectFromUTC(s) {
s = s.split(/\D/);
return new Date(Date.UTC(+s[0], --s[1], +s[2], +s[3], +s[4], +s[5], 0));
}
and here's a shim for toISOString:
if (typeof Date.prototype.toISOString != 'function') {
Date.prototype.toISOString = (function() {
function z(n){return (n<10? '0' : '') + n;}
function p(n){
n = n < 10? z(n) : n;
return n < 100? z(n) : n;
}
return function() {
return this.getUTCFullYear() + '-' +
z(this.getUTCMonth() + 1) + '-' +
z(this.getUTCDate()) + 'T' +
z(this.getUTCHours()) + ':' +
z(this.getUTCMinutes()) + ':' +
z(this.getUTCSeconds()) + '.' +
p(this.getUTCMilliseconds()) + 'Z';
}
}());
}
This happens because date is printed using toString method which by default returns the date and time in local timezone. The method toUTCString will give you the string you need.
Date actually keeps the date as unix time in milliseconds and provides methods to manipulate it.
In vanilla javascript there isn't a way to create a date that assumes the local time of the ISO formatted string you give it. Here's what happens when you pass an ISO 8601 formatted string to javascript. I'm going to use a non UTC time as it illustrates the problem better than using an ISO formatted string:
var startTime = new Date("2013-03-10T02:00:00+06:00"). Note this could also be 2013-03-10T02:00:00Z or any other ISO-formatted string.
read the time, apply the offset and calculate milliseconds since 1970-01-01T00:00:00Z
You now have only milliseconds - you have lost all timezone info. In this case 1362859200000
All functions, apart from the ones that give you a UTC representation of that number, will use the timezone of the computer running the code to interpret that number as a time.
To do what the original poster wants, you need to.
parse the ISO string, interpret the offset ('Z' or '+06:00') as the timezone offset
store the timezone offset
calculate and store the ms since epoch, using the offset timezone offset
hold that offset
whenever attempting to make a calculation or print the date, apply the timezone offset.
This isn't trivial, and requires a complete interpretation of the 8601 spec. Way too much code to put here.
This is exactly what moment.js is designed to do. I strongly recommend using it. Using moment.js:
moment("2013-03-10T02:00:00Z").format()
"2013-03-10T02:00:00Z"
this will result in printing the ISO time of the original string, preserving the offset.
you can try moment js library https://momentjs.com
For my case, I had 2022-10-17T01:00:00 on my database. SO I need to format it to the 01:00:00 AM.
So here was my solution.
var date = "2022-10-17T01:00:00"
var timeFormat = moment(date ).format('HH:mm A');
output: 01:00:00 AM
it will return ISOdate
var getDate = () => {
var dt = new Date();
var off = dt.getTimezoneOffset() * 60000
var newdt = new Date(dt - off).toISOString()
return newdt.slice(0, 19)
}
Output