I'm using moment.js to format a datetime value as follows:
time = moment(this.params['timeValue']).format("HHmmss.SSS")
Here, this.params['timeValue'] is a string. An example value is 2020-02-05 10:00:00.123 . formatting using moment returns the value 100000.123. Sometimes my datetime value goes to microsecond value, but moment js seems to cut the formatted value to millisecond level. For example formatting 2020-02-05 10:00:00.123456 returns 100000.123. I've tried this, but it did not work:
time = moment(this.params['timeValue']).format("HHmmss.SSSSSS")
Could you help me how to handle the formatting of a datetime value with microseconds. If moment.js doesn't handle it, is there any other library I could use?
Moment.js wraps the native date type, which goes down to only milliseconds. You will only get the first three digits, the moment.js documentation shows an example of the fractional seconds (as per your second code snippet), but also mentions that it will only display the 3 significant digits, filling the rest with zeros.
Check out this SO question for more information about microseconds in JavaScript.
Related
I have a timestamp from the backend and I want to display it with momentjs per console.log() without timeshifting and completly indepented from my browsers timezone. I read many posts on stackoverflow but nothing works. All of my outputs have some timezone included.
let timestamp = "2019-11-19T07:05:00+01:00";
console.log(moment(timestamp).toISOString(true));
console.log(moment.utc(timestamp).format());
console.log(moment.utc(timestamp).toISOString(true));
console.log(moment.parseZone(timestamp).format());
console.log(moment.parseZone(timestamp).local().format());
console.log(moment.parseZone(timestamp).utc().format());
console.log(moment(timestamp).utcOffset(timestamp).toISOString(true));
console.log(moment.tz(timestamp, 'Europe/Berlin').toISOString(true));
console.log(moment.tz(timestamp, 'Europe/Berlin').format());
console.log(moment.tz(timestamp, 'Europe/Berlin').unix());
console.log(moment.parseZone(timestamp).format('MM/DD/YYYY HH:mm:ss'));
console.log(moment(timestamp).utcOffset("+0100").format('YYYY-MM-DD hh:mm:ss'));
expected output:
2019-11-19T07:05:00Z
The Timezone of the timestamp is: Europe/Berlin
My Browsers timezone is switched to something different.
I don't understand why this simple problem has no easy solution. :)
To meet the requirement you described (keeping the local time while changing the offset) you can do the following:
var result = moment.parseZone("2019-11-19T07:05:00+01:00").utcOffset(0, true).format();
console.log(result); //=> "2019-11-19T07:05:00Z"
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Step by step explained:
moment.parseZone("2019-11-19T07:05:00+01:00") // Parses the string, retaining the offset provided
.utcOffset(0, true) // sets the offset to zero while keeping the local time
.format() // formats the output, using Z to represent UTC
However - You should recognize that these are not the same moments in time. The output timestamp is one hour earlier than the input timestamp. This is explained in the documentation as follows (emphasis mine):
The utcOffset function has an optional second parameter which
accepts a boolean value indicating whether to keep the existing time
of day.
Passing false (the default) will keep the same instant in Universal Time, but the local time will change.
Passing true will keep the same local time, but at the expense of choosing a different point in Universal Time.
Thus, it is usually the wrong choice when you already have a specific point in time, either in UTC or as an offset from UTC (like your example input value).
Instead, you should expect that converting from local time to UTC will indeed change the date and time portion of the timestamp. You can use .utcOffset(0, false), or .utcOffset(0), or simply .utc() to do the conversion correctly.
I use the below code to format date time in iso format using java (I'm reducing 1 min from current time) and get the output as this "2016-03-17T11:38:21.xxxZ" < x represent some numbers> i want this to compare with the time which have mentioned in the DB.
Person who build that data insert query, he used javascript to get the time and format it in iso.
Date inside the DB is looks like this "2016-03-17T06:09:21.530Z" and its actual time is "11:39:21 GMT+0530 (India Standard Time)" which is similar to my current time but I'm comparing these two dates as string. and get 1min early data from DB.In that case i can't get an out put because as strings these two aren't match. can anybody recomand a solusion ?
I use OrientDB
Java Code
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Calendar date = Calendar.getInstance();
long t = date.getTimeInMillis();
date.setTimeInMillis(t);
date.set(Calendar.MINUTE, date.get(Calendar.MINUTE) - 1);
String time1minEarly = df.format(date.getTime());
Using Calendar.set() and Calendar.get() does not modify the date in a way you intend:
This will modify the minutes field in your case. So subtracting "1" will reduce the minute but not give a viable date for cases where minute initially is zero.
You may just subtract a minutes of milliseconds from your "t" variable to get a true minute offset.
And for ease of use you might also consider following advise from #Prashant and using LocalDateTime class from joda library.
Thanks Everybody for your support.
I figure out How to do this. it's pretty easy. Both #rpy and #Prashant are correct. Calendar is not suitable for solve my issue. Also LocalDateTime too. but it did help me to figure out the correct way.
#rpy and #Prashant they both did miss one thing that the javascript time represent the UTC time. that's the issue. (it's 5.5 hours behind compared to my location) so, I figure out this below code. it did what i wanted to do.
It's pretty easy. all you have to do is provide your zone id.
(You can get Zone id using this code : go to the link - http://www.javadb.com/list-possible-timezones-or-zoneids-in-java/)
Also you can choose so many formats by changing "DateTimeFormatter" value.
ZoneId UTCzoneId = ZoneId.of("UTC");
ZonedDateTime time1minEarly = ZonedDateTime.now(UTCzoneId).minusMinutes(1);
String UTCtime1minerly = time1minEarly.format(DateTimeFormatter.ISO_INSTANT);
Out put is similar to this : "2016-03-17T10:39:21.530Z"
(- UTC time at that time : 2016-03-17T10:40:21.530Z)
We are using the Kendo datetimepicker, implemented using the AngularJS directives:
<input type="text" kendo-date-time-picker k-ng-model="TheDateModel">
Where: TheDateModel = 2016-02-15 20:58:24.0000000 +00:00
I am in the CST timezone, which is -6 hour offset from the GMT. The current result of the datetimepicker shows a time of 8:58 pm but my expected result is 2:58 pm.
What in the world am I doing wrong?
Disclaimer: I work for Kendo UI team
The Kendo UI Datepicker uses JavaScript Date object internally to hold the selected date value. As you probably know, it always uses the local (browser) timezone. We tried to explain that caveat in our docs too:
JavaScript Date Object - Basics
Due to this default behavior, the widget will use the already converted Date value (with the applied local timezone). The widget doesn't manipulate the value timezone, as it does not have sufficient information how to do that.
Solution
The best approach in this case is to convert the Date strings (like the one you mentioned "2016-02-15 20:58:24.0000000 +00:00") manually before feed the DatePicker widget. For instance, here is one possible approach to do that:
http://dojo.telerik.com/EyuRA
Notice how the value is parsed and then adjusted in the loadData method. Similar thing should be done by the developer that needs to handle different TZ in their app.
I've been down this road and had to implement this:
http://www.telerik.com/support/code-library/using-utc-time-on-both-client-and-server-sides
So I found the solution to my problem. First off for clarity, and sorry for the misinformation, but my date was coming down from the server as 2016-02-15T20:58:24.0000000+00:00 - add the T and remove all spaces.
All that needed to be done was to add the k-parse-formats attribute to the directive as follows:
<input type="text" kendo-date-time-picker k-parse-formats=['yyyy-MM-ddTHH:mm:sszzz'] k-ng-model="TheDateModel">
Boom, considers the offset and your current timezone, and correctly parses and displays the date and time. Just be aware, that when you specify your own parse formats, to include all possible formats that your dates could be.
For example, I then ran into a problem where I had milliseconds greater than 0 coming through on my dates: 2016-02-15T20:58:24.1234567+00:00. This broke the datetimepicker again. Simpler fix: just changed my parsing format to: yyyy-MM-ddTHH:mm:ss.fffffffzzz. Make sure the number of f is greater than or equal to the number of possible milliseconds.
<input type="text" kendo-date-time-picker k-parse-formats=['yyyy-MM-ddTHH:mm:ss.fffffffzzz'] k-ng-model="TheDateModel">
I want to convert javascript time stamps to erlang dates. I am using the qdate library to help me do that since it also provides functions for date arithmetic.
Calling it's to_date function first before midnight and then after midnight results in time displacement of 24 hrs. For example:-
qdate:to_date(Timestamp div 1000).
%% {2015,5,2} before midnight
qdate:to_date(After_midnight_Timestamp div 1000)
%%{2015,5,2} after midnight should be 3 instead of 2
I googled around a bit and found this in the erlang calender docs
The time functions local_time/0 and universal_time/0 provided in this module both return date and time. The reason for this is that separate functions for date and time may result in a date/time combination which is displaced by 24 hours. This happens if one of the functions is called before midnight, and the other after midnight. This problem also applies to the Erlang BIFs date/0 and time/0, and their use is strongly discouraged if a reliable date/time stamp is required.
I am having trouble understanding this. Which one of the functions from local_time/0 and universal_time/0 always gives the correct results? By correct I mean I want the right date to be shown after midnight. The resolution of the time is only {y,m,d}. Don't care for hours, minutes and seconds or anything finer than that.
So how do I reliably convert a javascript timestamp to a date in erlang?
Looks like it was just a timezone issue :) Since I was working with javascript timestamps the default timezone of the javscript time stamp is my localtimzone which is "IST". Now internally when qdate sees an integer in qdate:to_date(Timestamp). it automatically selects a UTC timezone for it. Relevant code on line 256:-
raw_to_date(Unixtime) when is_integer(Unixtime) ->
unixtime_to_date(Unixtime);
%% other clauses
and on line 654
unixtime_to_now(T) when is_integer(T) ->
MegaSec = floor(T/1000000),
Secs = T - MegaSec*1000000,
{MegaSec,Secs,0}.
unixtime_to_date(T) ->
Now = unixtime_to_now(T),
calendar:now_to_datetime(Now).
The final clue comes from the erlang calendar documentation itself
now_to_datetime(Now) -> datetime1970()
Types: Now = erlang:timestamp()
This function returns Universal Coordinated Time (UTC) converted from the return value from erlang:now().
So the solution to this problem was to simply supply an IST string with qdate:to_date() like so:-
qdate:to_date("IST",Timestamp div 1000)
and it started returning correct dates. I wasn't sure of the solution so I ran a test with qdate:to_date(erlang:now()) and the value returned was exactly 5:30 hrs behind my clock time. So it seems that supplying the timezone string works :)
I have the following line of javascript using MomentJS
var date = moment('20/04/20000', 'DD/MM/YYYY'); //notice year twenty thousand
alert(date.format()); // alerts "2000-04-20T00:00:00+01:00"
If I change the format to DD/MM/YYYYY it works as expected, except of course if I enter a 6 digit year. I know this is arbitrary, but it bothers me. How do I use a format that will expect any amount of digits in the year?
It looks like moment ignores any extra format specfiers. So you can just use as many Y's as you expect you'll need for your max date. For example this code tells moment to expect 10 digit years:
moment('20/04/20000', 'DD/MM/YYYYYYYYYY').format();
but it's return value looks like what you're expecting, 5 digit year:
"20000-04-20T00:00:00-04:00"
This is not a documented feature, and I'd be very careful about this code as you use future moment updates. Protect this code with unit tests for sure.