Convert TimeZone offset to TimeZone text - datetime

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.

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>

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.

Why is the conversion from EST to UTC +5 hours and not +4? [duplicate]

This question already has answers here:
How to make a timezone aware datetime object
(15 answers)
Closed 6 years ago.
I've got a datetime which has no timezone information. I'm now getting the timezone info and would like to add the timezone into the existed datetime instance, how can I do?
d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')
How to add the timezone info tz into datetime a
Use tz.localize(d) to localize the instance. From the documentation:
The first is to use the localize() method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information):
>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500
If you don't use tz.localize(), but use datetime.replace(), chances are that a historical offset is used instead; tz.localize() will pick the right offset in effect for the given date. The US Eastern timezone DST start and end dates have changed over time, for example.
When you try to localize a datetime value that is ambiguous because it straddles the transition period from summer to winter time or vice-versa, the timezone will be consulted to see if the resulting datetime object should have .dst() return True or False. You can override the default for the timezone with the is_dst keyword argument for .localize():
dt = tz.localize(naive, is_dst=True)
or even switch off the choice altogether by setting is_dst=None. In that case, or in the rare cases there is no default set for a timezone, an ambiguous datetime value would lead to a AmbiguousTimeError exception being raised. The is_dst flag is only consulted for datetime values that are ambiguous and is ignored otherwise.
To go back the other way, turn a timezone-aware object back to a naive object, use .replace(tzinfo=None):
naivedt = awaredt.replace(tzinfo=None)
If you know that your original datetime was "measured" in the time zone you are trying to add to it, you could (but probably shouldn't) use replace rather than localize.
# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)
I can imagine 2 times when this might make sense (the second one happened to me):
Your server locale is set to the incorrect time zone and you are trying to correct a datetime instance by making it aware of this incorrect timezone (and presumably later localizing it to the "correct" time zone so the values of now() match up to other times you are comparing it to (your watch, perhaps)
You want to "tag" a time instance (NOT a datetime) with a time zone (tzinfo) attribute so that attribute can be used later to form a full datetime instance.

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

Is this a standard format for saving timezone rules?

I am doing some "software archaeology" on python-dateutil to fully document (and tighten up) the formats accepted by dateutil.tz.tzstr, and I have come across a strange timezone format that is obviously intended to be explicitly supported (link goes to the code):
# GMT0BST,3,0,30,3600,10,0,26,7200[,3600]
Just reading the code, I've figured out how it works. It starts out like a TZ environment variable:
GMT: Standard time abbreviation
0: Standard offset (in hours)
BST: DST abbreviation
Then the rest is a comma-delimited list, broken into two parts:
3,0,30,3600: DST->STD transition time specifier - month, week of month, day of week, seconds after midnight that the transition happens (note that when "week of month" is 0, the number following is actually the day of the month)
10,0,26,7200: STD->DST transition time specifier - same as above
[,3600]: If specified, this says how big the offset is during DST (default is 1 hour)
The GNU TZ variable equivalent to this string is GMT0BST,J89/1,J299/2:
>>> from dateutil import tz
>>> tz1 = tz.tzstr('GMT0BST,3,0,30,3600,10,0,26,7200')
>>> tz2 = tz.tzstr('GMT0BST,J89/1,J299/2')
>>> tz1 == tz2
True
Is this a standard timezone format somewhere, or just something that one of the earlier maintainers of dateutil added? It seems somewhat strange to add a custom time zone format that expresses exactly the same thing a GNU TZ variable does, but I only ever see "IANA database" and "POSIX TZ variable" as formats when searching for time zone rules.
No, that's not a standard format of any kind (AFAIK). Must be something internal to dateutil.
Note that this appears to be for Europe/London, and the correct POSIX string (for current years) would be GMT0BST,M3.3.0/1,M10.5.0

Resources