MomentJs and Timezone Abbreviations - momentjs

I am having trouble with the momentjs library
the line
moment("Mon Oct 14 01:00:00 GMT 2013") parses correctly
but the line
moment("Mon Oct 14 01:00:00 BST 2013") throws an invalid date
I have tried building a format string but the zz format which is what I think I need is deprecated, is there a way to make it skip the BST/GMT bit completely as I am only interested in the date
Thanks in advance.

Time zone abbreviations aren't unique, so they cannot be parsed. You can ignore it by putting any non-format character as a placeholder:
moment("Mon Oct 14 01:00:00 BST 2013","ddd MMM DD HH:mm:ss ? YYYY")
But you should be aware that by ignoring it, you'll be assuming the local time zone of the computer where the code is running. Set your computer for another time zone and call .format() on this and you'll see what I mean.
Perhaps you don't care about time zones and just want to reformat this to something else. That's fine, but what if you provide a date that's invalid because of a daylight saving time transition in the computer's local time zone? Your browser will either skip backward or forward depending on which browser your running. To avoid that, you should work in UTC instead of in the local time. Even though your input value is from some other time zone entirely, working in UTC will ensure it doesn't get mangled.
moment.utc("Mon Oct 14 01:00:00 BST 2013","ddd MMM DD HH:mm:ss ? YYYY")

Related

How to format a date-time to display the timezone in IANA format?

The following code
fmt.Println(time.Now().Format("2 Jan 2006 03:04:05PM MST"))
prints
26 Nov 2021 04:00:31PM GMT
How to format the timezone as Europe/London i.e. in the IANA format? The expected output is
26 Nov 2021 04:00:31PM Europe/London
There isn't an option to do this directly with the time format layout.
However Location.String will print the IANA name in most cases.
String returns a descriptive name for the time zone information, corresponding to the name argument to LoadLocation or FixedZone.
And LoadLocation usually takes the IANA string as input:
If the name is "" or "UTC", LoadLocation returns UTC. If the name is "Local", LoadLocation returns Local.
Otherwise, the name is taken to be a location name corresponding to a file in the IANA Time Zone database, such as "America/New_York".
Now "Local" isn't a valid IANA name, but "UTC" is — well, actually UTC is an alias of Etc/UTC.
The other gotcha with the std time package is that Location.String will print the name passed to FixedZone, and that can be literally anything.
So, if you are able to make assumptions about how your time.Location are instantiated, the following might be a viable solution:
fmt.Printf("%s %s", t.Format("2 Jan 2006 03:04:05PM"), t.Location())
Otherwise you will have to use some third-party package, or roll out your own mapping.

Convert TimeZone offset to TimeZone text

I have a string in format "2019-04-25T16:34:28-05:00". I have parsed the string by joda-time by pattern "yyyy-MM-dd'T'HH:mm:ssZ".
DateTimeFormatter df = DateTimeFormat.forPattern(formatStr);
DateTime temp = df.parseDateTime(dateStr);
And it giving me the output in DateTime as "2019-04-25T15:34:28.000-06:00".
Until this all seems correct but I am wanting the output with TimeZone text like "04-25-2019 03:34 PM CDT".
I am formatting the DateTime object by:
DateTimeFormatter format = DateTimeFormat.forPattern("MM-dd-yyyy
hh:mm a z");
but I am getting -06:00 still the output as "04-25-2019 03:34 PM -06:00".
How can I get the timezone name like "CDT" in place of offset?
How can I get the timezone name like "CDT" in place of offset?
You can't. -05:00 might be CDT, but it is also an offset that could apply to a large number of other time zones. For example, EST in the US, or perhaps ACT in Brazil or PET in Peru, or many others...
Even if you were to limit this problem to US time zones, consider that MST and PDT are both UTC-7, though MST applies year-round in most of Arizona while PDT only applies during daylight saving time in the Pacific time zone. If you are given a timestamp in the summer with a -07:00 offset, it is impossible to tell which it belongs to, even constrained to the US.
In other words, in order to know which abbreviation to use, you must provide a time zone identifier (such as America/Los_Angeles), not just an offset.
See also "Time Zone != Offset" in the timezone tag wiki.

ISO 8601 Datetime understanding

I am trying to understanding the date reading of ISO 8601 format and cant find a good doc to read.
If I am getting time in my code like this "2018-08-18T00:00:00+1000", is this local time or UTC time?
and when I convert it using Convert.ToDateTime("2018-08-18T00:00:00+1000"), I get the following date time {8/17/2018 7:00:00 AM}. I am not sure if that is UTC datetime or local?
What is the math behind "2018-08-18T00:00:00+1000" getting converted to {8/17/2018 7:00:00 AM}, I cant get my head around this.
You are asking for the math behind 2018-08-18T00:00:00+1000 being shown as 8/17/2018 7:00:00 AM.
First of all 8/17/2018 7:00:00 AM is just another format to display the date and time. Converted to an ISO 8601 string it would look like this: 2018-08-17T07:00:00.
+1000 at the end of the 2018-08-18T00:00:00+1000 representation is a timezone offset. You could read that string as August 18, 2018 in UTC plus ten hours. So it would be the same as 2018-08-18T10:00:00Z.
So we have a UTC date of August 18, 2018 10 AM, which is shown as a locale date of August 17, 2018 7 AM. That would mean that you are in a timezone which is 27 hours behind UTC.
A timezone behing more than 12 hours before (or 14 after) UTC does not exist (as far as I'm aware of). Therefore I assume that you have a typo in your example. Another reason could be a totally broken date parser.
But I still hope you got the math behind the conversion.

How to get start and end date with momentjs?

I get the start date of my calendar like this:
var date_start = $('#calendar').fullCalendar('getView').start
with .toDate() I can see this result in chrome console:
Mon Nov 09 2015 01:00:00 GMT+0100 (ora solare Europa occidentale)
I need to display this result:
Mon Nov 09 2015 00:00:00
I also want get the end of the day, should be this:
Tue Nov 10 2015 00:00:00
How I can achieve this result?
toDate gives you back a JavaScript Date object. Any output string is therefore based on the specific implementation of Date.toString. If you want specific output, you should instead format using moment's format function.
date_start.format("ddd MMM DD YYYY HH:mm:ss")
However, this will return 01:00 and you asked for 00:00. It's not clear if you are asking for the local start-of-day, or if you're asking for the equivalent UTC value.
If you wanted the local start of the day:
date_start.clone().startOf('day').format("ddd MMM DD YYYY HH:mm:ss")
If you wanted the equivalent UTC value:
date_start.clone().utc().format("ddd MMM DD YYYY HH:mm:ss")
Cloning is important, as moment objects are mutable. If you don't clone, then you'll be manipulating the original moment, which could have unintended side effects in fullcalendar. You can use either the clone function shown above, or you can wrap it in the moment function, as in moment(date_start)... Both do the same thing.
For the ending value, looks like you want the start of the next day, so do this:
date_start.clone().startOf('day').add(1, 'day').format("ddd MMM DD YYYY HH:mm:ss")
Or:
date_start.clone().utc().add(1, 'day').format("ddd MMM DD YYYY HH:mm:ss")
Again, pick the one that corresponds to your usage scenario.
FYI - you seem to be asking for UTC, but in the vast majority of cases, local time is more relevant when displaying a calendar such as fullcalendar to a user.

AngularJS date filter incorrect time

I have a date object formatted to isotime. I'm using the |date filter to nicely format this in my template, but it incorrectly changing the time.
This Code...
<td>[[ user.last_online | date:'dd MMM yyyy - hh:mm a' ]]</td>
<td>[[ user.last_online ]]</td>
Results in this...
Now I know that the 1 hour difference is because of the Timezone, this is what I'm expecting. The Minutes however is incorrect.
In the first row, 13 minutes gets added when the filter is applied.
In the second row, 5 minutes gets added.
Not only are these two values wrong, but they are also inconsistent.
If you check ISO8601, you can see the correct time stamp format is
yyyy-MM-ddTHH:mm:ss.SSSZ
The milliseconds should consists of 3 digits. I did a simple test and you can see after correcting the milliseconds part, the dates will be rendered correctly.
{{"2013-08-09T15:36:31.764546+02:00" | date:'dd MMM yyyy - hh:mm a'}}<br />
{{"2013-08-09T15:34:14.318753+02:00" | date:'dd MMM yyyy - hh:mm a'}}<br />
{{"2013-08-09T15:36:31.764+02:00" | date:'dd MMM yyyy - hh:mm a'}}<br />
{{"2013-08-09T15:34:14.318+02:00" | date:'dd MMM yyyy - hh:mm a'}}<br />
The result is
09 Aug 2013 - 09:49 AM
09 Aug 2013 - 09:39 AM
09 Aug 2013 - 09:36 AM
09 Aug 2013 - 09:34 AM
Demo
Update
Python's datetime.isoformat() return the time with microseconds 0 <= microsecond < 1000000. Angularjs doesn't like, though this format is correct according to ISO8601, since ISO8601 only requires one or more digits representing a decimal fraction of a second
So I guess you can use strftime to format it.
I think the value of user.last_online is incorrect or has a bad format. If you check ISO8601, you can see the correct time stamp format is:
yyyy-MM-ddTHH:mm:ss.SSSZ
My plunker
Your dates are correctly formatted. ISO8601 doesn't actually require any particular number of decimals. There could be anywhere from zero to 7 decimals or more. If you look at an actual copy of the ISO8601 spec, section 4.2.2.4 says the following:
... with as many digits as necessary following the decimal sign ...
There are a few older browsers where this mattered when passed directly to the new Date() constructor, but AFAIK those were consider bugs and were fixed.
You are experiencing a bug in AngularJS, which was fixed in version 1.1.5. You can find it referenced in their change log as follows:
date filter: correctly format dates with more than 3 sub-second digits (4f2e3606)

Resources