I am trying to parse in JAVA a date/time that I receive from an API.
The timestamp I receive looks like this: "Thu Feb 13 12:11:09 IST (Israel) 2014"
I am using Java's SimpleDateFormat, however I do not see anywhere how did the country name, with parentheses, arrive in this string, and how should I parse it.
Is this some standard format I don't know about?
UPDATE:
I am receiving this timestamp from an Android application. The funny thing is the exact same application, running on a different device gives me: "Tue Feb 04 17:36:31 GMT+02:00 2014"
GMT+2 is Israel as well, same timezone, different format... why??
I don't know where android manages the time zone name resources. Anyway, obviously the resource names were changed on this one device (by Google?) with the motivation to avoid duplicates. The abbreviation IST is not unique and can also stand for "Indian Standard Time" which maps to Asia/Colcata instead (while Israel time zone is Asia/Jerusalem).
If you cannot parse "IST (Israel)" then I assume following things: If you parse it by SimpleDateFormat directly on android device then it should probably work. But if you get this string remotely then you can only apply preprocessing of string (filtering out the country) because other devices will not necessarily manage and share the same time zone name resources. You might be able to check directly on android what resources are stored there by calling DateFormatSymbols.getZoneStrings().
Conclusion: You should consider such strings as device-dependent. For data exchange, such formats are not well designed. Instead of using such proprietary formats you should try to use ISO-strings in formats like "yyyy-MM-dd'T'HH:mm:ssXX". Does the API you use offer any alternative format?
Related
I'm looking to convert Sharepoint TimeZone information into a Java TimeZone object for use with my application which is using the Sharepoint REST API. I understand that Sharepoint stores all it's timestamps in UTC but, when using the REST API, some of the timestamps are returned time zone adjusted and some are not. The format is the same for both except, as you would expect, the UTC values end with a "Z" and the time zone adjusted values do not. So, it's easy enough to convert those to Java DateTime objects but if I want to consistently return UTC values to my callers, I will have to adjust the "non-Z" values to UTC. Sharepoint allows me to get the configured TimeZone information for the Sharepoint server but what I need is a mapping from that information to the Java TimeZone ids. What Sharepoint provides through REST looks like this:
Description: (GMT-07:00) Mountain Time (US and Canada)
Bias: 420
Daylight Bias: -60
Standard Bias: 0
It doesn't provide any information that might indicate, say, when DST starts etc. but I figured I wouldn't need to worry about that as long as I can map the Sharepoint "Description" to a Java TimeZone id. So, I'm hoping that someone has run into this need before or perhaps has some other suggestion as to how I might get the UTC values I need from Sharepoint's REST API.
Java uses IANA time zones.
Mappings exist for Microsoft Windows to IANA time zones in the CLDR supplemental data.
However, Sharepoint time zones are not quite the same as regular Windows time zones. Instead of using string time zone keys like the ones found in the Windows registry (or via the Id property of .NET's TimeZoneInfo class), they use integer ids that are specific to Sharepoint. You can find a partial list here, and a more updated (unofficial) list here.
The Sharepoint time zone description loosely matches the DisplayName of the Windows time zone, but it's not a perfect match. It's entirely possible that some of the Sharepoint time zones are not defined as Windows time zones.
Assuming you mapped each Sharepoint SPTimeZone numeric id to a TimeZoneInfo id, then you could use the CLDR data to convert from there to IANA time zones. And if you can run .NET code, then you can do this quite easily with the Noda Time library, as described here.
UPDATE
I went ahead and mapped these to reasonable equivalents. These aren't guaranteed to be 100% accurate, but I think it will give you what you need.
CSV spreadsheet for the full mapping
JSON for SharePoint ID to IANA TZ name - ready for you to use in any language
These are mostly matched using the roughly equivalent Windows time zone, then to the IANA zone using the primary CLDR mapping. The only exceptions were:
SharePoint zones 33 and 81 are separate, but matched to the single "SA Western Standard Time" windows zone. They map to IANA zones America/La_Paz and America/Manaus respectively.
SharePoint zones 41 and 92 are separate, but matched to the single "Magadan Standard Time" windows zone. They map to IANA zones Asia/Magadan and Asia/Kamchatka respectively.
I've started using Matt's mappings and they look spot on. However, I noticed with Sharepoint 2013 that there are 10 more on the end of the list Matt provided. So, using the lovely list of IANA Time Zones here, http://en.wikipedia.org/wiki/List_of_tz_database_time_zones I have added these to Matt's list with my best guess from the IANA list (yep, just a best guess so if you have feedback, let me know).
"SharePoint ID","SharePoint Description","IANA Time Zone"
"95","(UTC-11:00) Coordinated Universal Time-11","Etc/GMT+11"
"96","(UTC-02:00) Coordinated Universal Time-02","Etc/GMT+2"
"97","(UTC+12:00) Coordinated Universal Time+12","Etc/GMT-12"
"98","(UTC+02:00) Damascus","Asia/Damascus"
"99","(UTC+12:00) Magadan","Asia/Magadan"
"100","(UTC+03:00) Kaliningrad, Minsk","Europe/Kaliningrad"
"101","(UTC+02:00) Istanbul","Europe/Istanbul"
"102","(UTC+06:00) Dhaka","Asia/Dhaka"
"103","(UTC-03:00) Salvador","America/Bahia"
"104","(UTC+02:00) E. Europe","Europe/Chisinau"
I've read many a post here re: GWT date handling.
One in particular that struck a cord with me was this one
Sending a date and timezone from GAE server to GWT client
Anyhow, there's a need on a project I'm working on to be able to display days, hours, minute intervals as labels in a grid. My team has adopted an approach where all date/time instances are passed the client from the server in ISO8601 String format. The server time zone is to be respected by the client. The biz use case is that all date/time instances are in "market time", so that any browser that visits the app will see and work with dates in the "market time" timezone which happens to be GMT-05:00 (if Daylight Savings in effect) or GMT-06:00 (if Standard Time in effect).
I have posted some source on Github, here:
https://github.com/fastnsilver/gwt-datehandling-example
Particularly...
https://github.com/fastnsilver/gwt-datehandling-example/blob/master/src/main/java/me/fns/gwt/datehandling/client/util/CSTimeUtil.java
and the GWTTestCase
https://github.com/fastnsilver/gwt-datehandling-example/blob/master/src/test/java/me/fns/gwt/datehandling/client/util/CSTimeUtilTestGwt.java
in the hopes that someone can stare at the utility (and test) we're employing for date handling and help us see what we're not seeing.
EDIT
The basic problem is that CSTimeUtil#hoursInDay(Date) is not being calculated correctly in Production mode for "transition days" This method is used by other methods (like CSTimeUtil#dateToHour(Date) and CSTimeUtil#labelsForDay(Date)).
I have deployed our application with the current implementation of CSTimeUtil and it appears to work, but not quite. I'm really confused by alternate test results when e.g., mvn gwt:test is run in GWT Mode or Production Mode on Windows where the OS timezone is set to various timezones other than U.S. GMT-05:00 or GMT-06:00.
Based on some hints from Andrei and some serious blood, sweat and tears, I figured this out on my own. I have updated the code in Github, so if you're curious please go have a look there.
The basics:
Make sure all Strings are ISO8601 (no millis) compliant when sent from server to client and vice versa
Use DateTimeFormat.getFormat("yyyy-MM-ddTHH:mm:ss.SZZZZ") to format and parse dates
Retreive GMT-prefixed time zone info from java.util.Date in "Market time" using DateTimeFormat(Date, TimeZone), where TimeZone param is set as TimeZone.createTimeZone(TZ_CONSTANTS_INSTANCE.americaChicago()) and time zone String retrieved by TimeZone.getISOTimeZoneString(Date)
Generating days, see generateDay(Date, int) or hours generateHour(Date, int), from a source date had to take into consideration that an increment or decrement coudl trigger a change in time zone offset if occurring on a "transition day".
If you time zone is fixed, why would you use a string to represent date/time? You can send a standard Java Date object to the client. If you want, you can even store all dates and times as Longs and pass Longs only. You also send the GWT's TimeZone Json string for your time zone (once per session). You can find it in the GWT - there is a file with strings for all time zones.
On a client you use DateTimeFormat with many predefined formats to display whatever you need: full date, month and date, date and time, etc. Just remember to create TimeZone object from this Json string and use it in DateTimeFormat.getFormat(...).format(Date, TimeZone).
With this approach you don't have to worry about DST changes (they are encoded in that Json string) and locales. You only pass simple Date or Long objects.
G'day All
If you create a date item in the plist editor of Xcode or Apple's standalone plist editor you get something of the form <date>2010-05-29T10:30:00Z</date> which is a nice well formed ISO date at UTC (indicated by the "Z"). Because I'm in timezone UTC +10 when that's read into my app & then displayed I get 8:30 PM out, still good. However if that is a time in my timezone it should be <date>2010-05-29T10:30:00+10</date> (replacing "Z" with my timezone offset). All of my attempts at reading such dates into my iPhone app have had the plist rejected as if it is malformed & editing a plist with such a date in Apple's editors changed the "+10" to "Z" without adjusting the time.
Do others think I'm correct in thinking this is a bug in either plist or Xcode? My feeling is that the implementation of ISO date & time in plist is incomplete.
Cheers, Pedro :)
It's not a bug in either. In CoreFoundation (and Foundation), all dates are represented in Zulu time, which is why they are serialized that way. The date is then formatted for display based on the timezone of the device that wishes to display it. Although this is an ISO date string, the only valid time zone for CoreFoundation/Foundation is Zulu time.
If, for some reason, you need to track the time zone that any given date was generated in, you should track this as a separate property. If you need to write an XML property list from somewhere else, you must first convert the date to zulu and then write it out (although the documentation clearly specifies that these keys are for debugging aids/readability only and may change in the future). This makes plists a decent way to serialize data between two Cocoa/CoreFoundation applications, but a less suitable way of serializing data between a Cocoa/CoreFoundation app and some other application.
I'm using GWT on the client (browser) and Joda Time on the server. I'd like to perform some DB lookups bounded by the day (i.e. 00:00:00 until 23:59:59) that a request comes in, with the time boundaries based on the user's (i.e. browser) timezone.
So I have the GWT code do a new java.util.Date() to get the time of the request, and send that to the server. Then I use Joda Time like so:
new DateTime(clientDate).toDateMidnight().toDateTime()
The trouble of course is that toDateMidnight(), in the absence of a specified TimeZone, will use the system's (i.e. the server's) TimeZone. I've been trying to find a simple way to pass the TimeZone from the browser to the server without much luck. In GWT I can get the GMT offset with:
DateTimeFormat.getFormat("Z").fmt(new Date())
which results in something like "-0400". But Joda Time's DateTimeZone.forID() wants strings formatted like "America/New_York", or an integer argument of hours and minutes. Of course I can parse "-0400" into -4 hours and 0 minutes, but I'm wondering if there is not a more straightforward way of doing this.
You could use java.util.Date's getTimezoneOffset() method. It's deprecated, but that's pretty usual for Date handling in GWT currently.
And AFAIR, you can specify something similar to "UTC+4" in Joda time.
Update: I looked it up, and it's "+04:00". Or use DateTimeZone.forOffsetHours() or even forOffsetMillis().
Gwittir (http://www.gwtsite.com) is a library for GWT that includes many cool utilities, like databinding, animation, reflection, and more. However, there are some other interesting goodies as well like the new Joda Time integration. If you have ever been frustrated by GWT’s lack of java.util.Calendar support, you’ll love this, as it makes it easy to do date manipulations in your applications.
otherwise, there are other ways to get timezone offset with + & -.
import java.util.TimeZone;
use: TimeZone.getDefault().getRawOffset()
this function will return the offset time in millisecond about your phone seeting. For Example, GMT-04:00 is equals to (-4)*60*60*1000 = -14400000.
After some operations to get the number which you want.
I have a similar but slightly different problem I think.
I actually need to store the clients timezone on the server, so that I can send out messages about dates stored in their calendar.
The dates are stored in UTC time in google app engine and of course I can store the current Timezone offset when creating the appointment. The problem comes when for instance I want to send out a summary email with a list of upcoming appointments in it. These appointments need to be offset with the correct Timezone adjustments for the client (Im happy to assume that they are still in the same timezone as when they created the appointment).
The real problem comes with Daylight Savings adjustments, so for instance I might have appointments stored for Saturday 30th October 2010 at 1pm (BST[GMT+60]) and Monday 1st November 2010 at 1pm (GMT).
So as you can imagine, I cant just use the current timezone offset (BST) as that would mean that the appointment on Monday 1st November would be listed as 2pm rather than 1pm (GMT+60)
It occurs to me that the best way to deal with this is just to store the timezone offset with each appointment individually, but I feel it would be much better to be able to determine the original timezone correctly in the first place, then just let java do the correct adjustments.
I've noticed that on some devices the NSTimeZone's name method for a particular timezone can return different values. When testing the Brisbane time zone, my device returns #"Australia/Brisbane" whereas another user's device returns "Etc/GMT-10". Both iPhone's are running 3.1.2.
The Date and Time Programming Guide for Cocoa states that:
timeZoneWithName: The name passed to this method may be in any of the
formats understood by the system, for
example EST, Etc/GMT-2,
America/Argentina/Buenos_Aires,
Europe/Monaco, or US/Pacific, as shown
in the following code fragment.
I'd just like to know what could determine which value is used? The device? The language?
I've discovered what the reason for this was.
When manually setting the timezone from Apple's build-in list, the correct and exact timezone name is returned. However, some mobile carriers provide the current time zone offset over the air, and if this is the case, Apple provide an "Automatic" setting which allows the iPhone to change time zone automatically when they move across into another time zone.
The problem is that while the current GMT offset is provided, there's no way to tell what latitude the user is at. Obviously, there may be for example, several cities in Australia with the a time zone of GMT -10. Therefore, no specific time zone name is available, only that the phone is currently GMT -10.
I've never scene what you describe. In my experience it returns the name you created it with.
In any case, if you're using the name for UI display, you should call [NSTimeZone localizedName:locale:] to force the name style you want.