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

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.

Related

Issue with luxon date time parsing when zone is present in string

I am seeing error the input "06/09/22 02:14 CDT" can't be parsed as format MM/dd/yy HH:mm ZZZZ` when trying to get luxon date time from string.
DateTime.fromFormat("06/09/22 02:14 CDT","MM/dd/yy HH:mm ZZZZ")
Not sure what is the valid format I need to use when there is time zone in date string.
Thanks.
Issue is that you input contains CDT that is not recognized by Luxon since ZZZZ is not a valid token as explained in the Parsing -> Limitations section of the docs:
Not every token supported by DateTime#toFormat is supported in the parser. For example, there's no ZZZZ or ZZZZZ tokens. This is for a few reasons:
Luxon relies on natively-available functionality that only provides the mapping in one direction. We can ask what the named offset is and get "Eastern Standard Time" but not ask what "Eastern Standard Time" is most likely to mean.
Some things are ambiguous. There are several Eastern Standard Times in different countries and Luxon has no way to know which one you mean without additional information (such as that the zone is America/New_York) that would make EST superfluous anyway. Similarly, the single-letter month and weekday formats (EEEEE) that are useful in displaying calendars graphically can't be parsed because of their ambiguity.
You can add fixed string 'CDT' in your format or remove it completely from your input. You can use zone option (America/New_York in the example above, or America/Chicago in your use case) of DateTime#toFormat to take into account timezone offset.
Example:
const DateTime = luxon.DateTime;
const dt1 = DateTime.fromFormat("06/09/22 02:14 CDT","MM/dd/yy HH:mm 'CDT'", {zone: 'America/Chicago'})
const dt2 = DateTime.fromFormat("06/09/22 02:14", "MM/dd/yy HH:mm", {zone: 'America/Chicago'})
console.log(dt1.toISO());
console.log(dt2.toISO());
<script src="https://cdn.jsdelivr.net/npm/luxon#2.4.0/build/global/luxon.min.js"></script>

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.

UNIX timestamp displays different date depending on timezone using Moment.js

I understand that UNIX is timezone independent. However, users from different countries are seeing different dates. For example I have a unix timestamp of 1545004800 (December 17th) which a user from Amsterdam submitted, but as a user in Los Angeles, I see the formatted date of December 16th.
I use the following line to convert the timestamp to a format like Dec 17, 2018
this.date = moment.unix(this.album.submissionReleaseDate).format("MMM DD, YYYY");
where this.album.submissionReleaseDate is 1545004800. Since the value is unix, it is timezone independent so why do I see a different date compared to my user in Amsterdam?
Here's a quick video where I show different timezones and how that affects the date that is displayed: https://youtu.be/-F7pieTljnc
I believe the fix was to do something like this instead:
this.date = moment.utc(moment.unix(this.album.submissionReleaseDate)).format("MMM DD, YYYY");

How to convert a String into an Ecto.DateTime in Elixir?

I need to convert a string containing a valid UTC time to an Ecto.DateTime one, which I will insert it into my database with the correct format later. I have tried using the Ecto.DateTime.cast(date) method but it doesn't seem to work. The string is Sat Aug 04 11:48:27 +0000 2012 and comes from the Twitter API.
I know there are libraries such as Timex which I didn't inspect yet. Is there any easy working solution already built in Elixir?
There's no built-in solution in Elixir or Erlang for parsing DateTime values of this format:
Sat Aug 04 11:48:27 +0000 2012
You can certainly write a parser yourself, but it's neither going to be short or simple. You'll have to split the string, get the values of both date and time parameters, convert month strings to month integers, parse the timezone, represent the complete value in Elixir/Erlang DateTime formats and then finally cast it to Ecto.DateTime. See the following links:
Elixir Tips - Date Parsing
Erlang - How Can I Parse RFC1123 Dates Into An Erlang Term?
Convert timestamp to datetime in erlang
Using Timex is the best option here.
It's a well written library that allows you to stay away from the chaos of inner workings of Date/Time. With Timex, you can parse your string like this:
"Sat Aug 04 11:48:27 +0000 2012"
|> Timex.parse!("%a %b %d %T %z %Y", :strftime)
|> Ecto.DateTime.cast!
# => #Ecto.DateTime<2012-08-04 11:48:27>
Note: Timex has built-in support for a lot of the common DateTime formats, and I found it weird that a DateTime format being sent by Twitter wasn't supported - so I wrote one for you. Maybe double check to see if your string is correct? Also take a look at Timex Parsing and Formatting documentation.

MomentJs and Timezone Abbreviations

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")

Resources