Convert to CST Using Joda API - timezone

Any one know how to convert UTC time to CST time using joda date time api ?
My code is something like this.
DateTimeZone zone = DateTimeZone.forID("CST");
DateTime mstTime = utcDateTime.toDateTime(zone);
Api says 'The datetime zone id CST is not recognised'

Short time-zone ids like "CST" are unclear and ambiguous, so they are not supported. Use a longer form, like "America/New_York".

Some of the three-letter time zones (EST and MST, for example) are included in the default time zone database used by Joda. Others (CST and PST, for example) are not. (See http://joda-time.sourceforge.net/timezones.html for more details.)
The time zone IDs supported by Joda can be obtained by calling org.joda.time.DateTimeZone.getAvailableIDs(), and that set does differ from those returned by java.util.TimeZone.getAvailableIDs().

You can use "CST6CDT" format of joda time.

Related

Joda DateTimeFormatter.parseDateTime is failing for General time zone('z')

Confused with the use of General time zone('z'). Joda is failing in below sample code. Can somebody help me to understand why the behavior is like this? How can I parse a date in differnt timezone using this format in Joda?
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
System.out.println(sdf.parse("2019.09.17 AD at 15:29:00 IST"));
DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");
System.out.println(dateCtxParamDateTimeObj.toDate());
}
Output
Tue Sep 17 15:29:00 IST 2019
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "2019.09.17 AD at 15:29:00 IST" is malformed at "IST"
at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945)
Edit: You need to tell Joda-Time what you mean by IST
Thanks go to HarryQ, who pointed me here to where this is documented.
DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
"IST", DateTimeZone.forID("Europe/Dublin")));
DateTimeFormatter pattern = DateTimeFormat.forPattern("yyyy.MM.dd G 'at' HH:mm:ss z");
DateTime dateCtxParamDateTimeObj = pattern.parseDateTime("2019.09.17 AD at 15:29:00 IST");
System.out.println(dateCtxParamDateTimeObj);
The output from this snippet is:
2019-09-17T15:29:00.000+01:00
Lowercase z in a format pattern string works differently when formatting and when parsing in Joda-Time. Joda-Time can format time zone names for all available time zones, but with default settings it can only parse a few back. Which it can parse is controlled by the default time zone names of the DateTimeUtils class. It comes with a map of 10 time zone abbreviations as documented in the DateTimeUtils.getDefaultTimeZoneNames method (link at the bottom): CST, MDT, GMT, PST, PDT, UTC, EDT, CDT, EST and MST. We can substitute with a different map. What I am doing above is substituting with a map of just one abbreviation for the illustration. This risks breaking other code, so a better approach for most purposes would be to build a map containing both the abbreviations that were there before and that or those that we want to be able to parse too.
The map I provided above assumes that IST is for Irish Summer Time (and on September 17, 2019, Ireland was using summer time (DST)). You hardly meant Israel Standard Time because Israel too used summer time, IDT. A third likely understanding is India Standard Time:
DateTimeUtils.setDefaultTimeZoneNames(Collections.singletonMap(
"IST", DateTimeZone.forID("Asia/Kolkata")));
2019-09-17T15:29:00.000+05:30
You notice that we now get offset +05:30 instead of +01:00, so a different point in time. The ambiguity may also be the reason why Joda-Time refuses to make its own assumption about what you intended and therefore needs us to tell it before it can parse the string.
Original answer
It’s a documented limitation in Joda-Time. From the documentation of DateTimeFormat:
Zone names: Time zone names ('z') cannot be parsed.
Also note that IST and many other time zone abbreviations are ambiguous, so if there is any way you can avoid parsing one, by all means do avoid it. IST may be for Irish Summer Time, Israel Standard Time or India Standard Time, and there’s no guarantee which of them you get, or if you may even get Iceland Standard Time.
If you insist, one possible solution is to follow the advice from the Joda-Time homepage:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
The DateTimeFormatter class of java.time (the modern Java date and time API) will attempt to parse a time zone abbreviation. Good luck.
Links
Joda-Time
Documentation of DateTimeUtils.getDefaultTimeZoneNames()
Related question: Why Joda DateTimeFormatter cannot parse timezone names ('z')
Documentation of DateTimeFormat
Joda-Time homepage
SO user HarryQ, who in comments under my answer to this duplicate question pointed me to the documentation of Joda-Time’s default time zone names.
Others
My answer here shows how to control the interpretation of IST while parsing when using java.time.

Map microsoft graph timezone to moment

I'm trying to map timezone returned by microsoft graph to something more understandable by moment js. There were few instances of timezone like Melbourne timezone is 'AUS Eastern Standard Time' and Brisbane timezone is 'E. AUS Standard Time'. This looks to be confusing and I was wondering if there is any set of predefined timezones I can look into to map those timezones to what I want.
What I've tried is looking to https://learn.microsoft.com/en-us/graph/api/resources/datetimetimezone?view=graph-rest-1.0 and https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones. Neither of them have 'E. AUS Standard Time' mentioned. I'm not sure if there are more timezones that are not in this list.
dateTimeTimeZone resource type supports timeZone property to be provided in Windows time zone format while Moment supports IANA format, Unicode CLDR project could be utilized as a reliable data source to map between the two.
For example, according to:
<mapZone other="AUS Eastern Standard Time" territory="001" type="Australia/Sydney"/>
the request:
GET https://graph.microsoft.com/v1.0/me/events
Prefer:outlook.timezone="AUS Eastern Standard Time"
will return events in AUS Eastern Standard Time Windows timezone which correspond to Australia/Sydney IANA time zone identifier
Another option would be to omit Prefer: outlook.timezone header from request, in that case values of dateTimeTimeZone values are getting returned in UTC.

Ruby on Rails convention for date time format from external source

Given rails has a convention for most common tasks, is there a format of date/time data that ruby/rails ingests most easily, or which it 'prefers'?
I will have date/time data coming from an external source, and I can choose how it's formatted (but it not be easy to change later). I have researched and found two recommended formats:
A string of format YYYY-MM-DD HH:MM:SS
Unix epoch time (i.e. number of seconds since 1 Jan 1970)
Does rails deal more easily with one of these formats over the other (or is there another convention?)
Additional note: I can see from this talk that it's almost always best to store time in UTC, so I have that much figured out
I would agree that Ruby on Rails default to using the UTC time zone at least in the database.
I do not see a strong convention what time string format Rails prefers, but I would always choose ISO 8601: 'YYYY-MM-DDTHH:MM:SSZ'

Mapping IANA/Olson timezone database to abbreviations (like EST, PST, etc)

I need to map IANA/Olson timezone id to abbreviations, like EST, PST, etc.
I understand that this is not 1-to-1 mapping and that, for example, for EST there are quite a bunch of IANA timezones.
Is there some kind of database/mapping I can use for this?
PS: JavaScript solution is preferable, but any info that could help me to build this mapping (IANA timezone id -> abbreviation) is appreciated.
The IANA TZDB source data does have abbreviations already, but they have to be computed for the date in question. You can see it in the example data here, in the Zone.FORMAT and Rule.LETTER/S columns.
Since time zone abbreviations like CST can be ambiguous, it is only recommended you use them for display to a human. Never attempt to use them going the other direction, because only a few will be recognized by most implementations, and they tend to be valid only for the USA.
Since you asked for code that could do this for you, look at the bottom half of the code in my answer of how to do this using Noda Time in .Net. (The top half is about translating from a Windows zone to an IANA zone first, which you don't need.)
You could look at one of the several TZDB libraries for JavaScript, but I'm not sure if any directly expose the abbreviation data or not. Besides, that's a bit heavy for something so small.
In java with joda-time, we can get time-zone abbreviation from iana id as below
DateTimeZone dz = DateTimeZone.forID("America/New_York");
String tzid = dz.getShortName(DateTimeUtils.currentTimeMillis());
//tzid will be 'EST'
String longerTimeZoneName = dz.getName(DateTimeUtils.currentTimeMillis());
//longerTimeZoneName will be 'Eastern Standard Time'

convert iso-8601 datetime to utc time rails

I have an ISO-8601 datetime stamp, and need to convert it into local time in GMT. What is the way to do it in Ruby on Rails? I have '1325233011', and need to convert it into local time in GMT standards.
I think what you're asking for is a locale time in GMT+5.
Given an ISO timestamp, 1325233011
When I convert this to a locale-based date/time
Time.at(1325233011) => '2011-12-30 03:16:51 -0500'
Take a look at the ruby-docs, http://www.ruby-doc.org/core-1.9.3/Time.html for more information. Ruby has robust Time and Date classes with many helper utilities. My machine is configured for GMT-5 so it returns the local time. It's easy to change the way timezone settings are interpreted in your program, but that's for another day. Hope this helps!
From Collegue's help got it
Time.at(1325233011).to_datetime
For Iso-8601:
Time.at(1325233011).to_datetime.iso8601
For verification of time correct conversion and comparision use this link
http://coderstoolbox.net/unixtimestamp/

Resources