I just wanted to get offset(+02:00) from TimeZone but seems like it is not working for IST, JST, EST, and BET.
TimeZone exchangeTimeZone = banker.getTimeZone();
String timeZone = ZonedDateTime.now(ZoneId.of(exchangeTimeZone.getID())).getOffset().getId();
It is returning error "Unknown time-zone ID: EST". Date object is not avilable with me.
Use ZoneId.SHORT_IDS
ZonedDateTime.now(ZoneId.of(exchangeTimeZone.getID(), ZoneId.SHORT_IDS))
.getOffset().getId();
TimeZone.toZoneId()
// Never do this in your code: Get a TimeZone with ID EST for demonstration only.
TimeZone tz = TimeZone.getTimeZone("EST");
String currentOffsetString = ZonedDateTime.now(tz.toZoneId())
.getOffset()
.getId();
System.out.println(currentOffsetString);
Output when running just now:
-05:00
Contrary to the one-arg ZoneId.of method that you used in your code, TimeZone.toZoneId() does handle the deprecated three letter abbreviations (which may be considered an advantage or a disadvantage depending on your situation and your taste). So the above code works with many such three letter abbreviations too, including EST.
I am only hesitatingly including the first code line above. There are several things wrong with it: We should not create old-fashioned TimeZone objects in our code but rely on the modern ZonedId and related classes from java.time, the modern Java date and time API. We should not rely on three letter time zone abbreviations either. They are deprecated, not standardized and typically ambiguous. EST, for example, may mean Australian Eastern Standard Time or North American Eastern Standard Time. To increase confusion some will expect you to get Eastern Time with summer time (DST) in summer. With TimeZone you don’t. You get a time zone that uses standard time all year. The same is not true for AST, PST nor CST.
However you often cannot control what you get from an API. And if you’re unlucky enough to get an old-fashioned TimeZone object with ID EST, the above code shows you the conversion you need to get into the realm of java.time.
You could try to find a mapping for an abbreviation you got:
public static ZoneId getFromAbbreviation(String abbreviation) {
return ZoneId.of(ZoneId.SHORT_IDS.get(abbreviation));
}
You could get the offsets like in this main:
public static void main(String[] args) {
ZoneId istEquivalent = getFromAbbreviation("IST");
ZoneId estEquivalent = getFromAbbreviation("EST");
ZoneId jstEquivalent = getFromAbbreviation("JST");
ZoneId betEquivalent = getFromAbbreviation("BET");
ZonedDateTime istNow = ZonedDateTime.now(istEquivalent);
ZonedDateTime estNow = ZonedDateTime.now(estEquivalent);
ZonedDateTime jstNow = ZonedDateTime.now(jstEquivalent);
ZonedDateTime betNow = ZonedDateTime.now(betEquivalent);
System.out.println("IST --> " + istEquivalent + " with offset " + istNow.getOffset());
System.out.println("EST --> " + estEquivalent + " with offset " + estNow.getOffset());
System.out.println("JST --> " + jstEquivalent + " with offset " + jstNow.getOffset());
System.out.println("BET --> " + betEquivalent + " with offset " + betNow.getOffset());
}
the output is
IST --> Asia/Kolkata with offset +05:30
EST --> -05:00 with offset -05:00
JST --> Asia/Tokyo with offset +09:00
BET --> America/Sao_Paulo with offset -03:00
As you can see, EST simply doesn't have a zone name, just an offset.
Related
I want to convert a String 24 May 2020 07:40 AM to date format Mon May 24 07:40:55 IST 2020. I tried using Calendar and SimpleDateFormatter but didn't find a solution. Any help is appreciated.
I want the return type to be Date since I have to compare it with a couple of Dates.
java.time
When you’ve got some Date objects — likely from a legacy API that you cannot afford to upgrade to java.time just now — I still recommend that you use java.time, the modern Java date and time API, for your comparisons.
In the following example I am using Instant from java.time, but you may use ZonedDateTime or some other modern type too.
DateTimeFormatter fromFormatter = DateTimeFormatter.ofPattern("d MMM uuuu hh:mm a", Locale.ENGLISH);
Date anOldfashionedDate = new Date(1_590_286_000_000L);
Date anotherOldfashionedDate = new Date(1_590_287_000_000L);
System.out.println("The Date objects are " + anOldfashionedDate + " and " + anotherOldfashionedDate);
String aString = "24 May 2020 07:40 AM";
Instant instantFromDate = anOldfashionedDate.toInstant();
Instant instantFromAnotherDate = anotherOldfashionedDate.toInstant();
Instant instantFromString = LocalDateTime.parse(aString, fromFormatter)
.atZone(ZoneId.of("Asia/Kolkata"))
.toInstant();
System.out.println("Comparing " + instantFromDate + " and " + instantFromString + ": "
+ instantFromDate.compareTo(instantFromString));
System.out.println("Comparing " + instantFromAnotherDate + " and " + instantFromString + ": "
+ instantFromAnotherDate.compareTo(instantFromString));
Output is (when running in Asia/Kolkata time zone):
The Date objects are Sun May 24 07:36:40 IST 2020 and Sun May 24 07:53:20 IST 2020
Comparing 2020-05-24T02:06:40Z and 2020-05-24T02:10:00Z: -1
Comparing 2020-05-24T02:23:20Z and 2020-05-24T02:10:00Z: 1
An Instant prints in UTC; this is what its toString method generates. The trailing Z means UTC. Since India Standard Time is 5 hours 30 minutes ahead of UTC, 07:40 AM in India is the same time as 02:10 in UTC.
Given that you embark on using java.time now, you are well prepared when one day your legacy API gets upgraded to using java.time too.
The opposite conversion
If you do insist on using Date, to answer your question as asked, the opposite conversion is easy too:
Date oldfashionedDateFromInstantFromString = Date.from(instantFromString);
System.out.println("Converting to old-fashioned: " + oldfashionedDateFromInstantFromString);
Converting to old-fashioned: Sun May 24 07:40:00 IST 2020
Link
Oracle tutorial: Date Time explaining how to use java.time.
I'm working on a critical application which cares about daylight saving time change.
I'm trying to simulate manually what could happen at runtime by comparing thow date which cross the daylight saving change, so I made the below test.
My current location is Italy so the change from CEST (Central European Summer Time) to CET (Central European Time) this year happens on 25/10.
I used the full time zone names, my timezone is Europe/Rome.
And here it is the test I did:
Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome DST")); //CEST
before.set(Calendar.DAY_OF_MONTH, 25);
before.set(Calendar.MONTH, Calendar.OCTOBER);
before.set(Calendar.HOUR_OF_DAY, 2);
before.set(Calendar.MINUTE, 30);
before.set(Calendar.SECOND, 0);
before.set(Calendar.MILLISECOND, 0);
System.out.println(before.getTime());
Calendar after = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome")); //CET
after.set(Calendar.DAY_OF_MONTH, 25);
after.set(Calendar.MONTH, Calendar.OCTOBER);
after.set(Calendar.HOUR_OF_DAY, 2);
after.set(Calendar.MINUTE, 30);
after.set(Calendar.SECOND, 0);
after.set(Calendar.MILLISECOND, 0);
System.out.println(after.getTime());
System.out.println(before.compareTo(after));
The output is:
BEFORE DST CHANGE: Sun Oct 25 03:30:00 CET 2015
AFTER DST CHANGE: Sun Oct 25 02:30:00 CET 2015
before.compareTo(after): 1
The comparison result is wrong, i.e. 2:30 CEST is after 2:30 CET, but its the opposite.
I don't know if it's a real test.
Is it Is there any way to fix this?
I tried also with joda time but the result is the same.
Thanks in advance.
Your problem is that "Europe/Rome DST" is not recognized by getTimeZone(timeZoneId).
When it doesn't understand your input, it returns the GMT timezone by default. You can see the list of available TimeZone ids with getAvailableIDs (the method below getTimeZone at the above link).
It should be noted that CEST is also not on the list. To simulate the CEST timezone you could choose one of the following solutions:
I would recommend using TimeZone.setRawOffset(int offsetInMs) to set the offests for CET and CEST yourself.
Use one of the timzones that is defined relative to GMT (ex, with id "Etc/GMT+1"). This will ensure that you are using valid timezone offsets the the TimeZone api will understand.
Set the DST offset on the calendar instance Calendar.DST_OFFSET.
By using the last solution the correct test code is:
Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
before.set(Calendar.DST_OFFSET, 3600000);
before.set(Calendar.DAY_OF_MONTH, 25);
before.set(Calendar.MONTH, Calendar.OCTOBER);
before.set(Calendar.HOUR_OF_DAY, 2);
before.set(Calendar.MINUTE, 30);
before.set(Calendar.SECOND, 0);
before.set(Calendar.MILLISECOND, 0);
System.out.println("BEFORE DST CHANGE: " + before.getTime());
Calendar after = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
after.set(Calendar.DAY_OF_MONTH, 25);
after.set(Calendar.MONTH, Calendar.OCTOBER);
after.set(Calendar.HOUR_OF_DAY, 2);
after.set(Calendar.MINUTE, 30);
after.set(Calendar.SECOND, 0);
after.set(Calendar.MILLISECOND, 0);
System.out.println("AFTER DST CHANGE: " + after.getTime());
System.out.println("before.compareTo(after): " + before.compareTo(after));
And the output:
BEFORE DST CHANGE: Sun Oct 25 02:30:00 CEST 2015
AFTER DST CHANGE: Sun Oct 25 02:30:00 CET 2015
before.compareTo(after): -1
The answer by augray is correct and should be accepted (click that large empty check mark icon to make it turn green). I'll add some thoughts and code.
Use A Good Date-Time Library
Avoid the mess that is the java.util.Date/.Calendard classes. They are notoriously troublesome, flawed in both design and implementation.
These classes have been supplanted by the new java.time package in Java 8 and later (Tutorial). That package was inspired by the Joda-Time library. While similar, java.time and Joda-Time are not identical. Each has features the other lacks. You can use either or both.
Avoid 3-4 Letter Time Zone Codes
Codes such as CET & CEST are neither standardized nor unique. Avoid them.
Use full time zone names. Most of these are "continent/city" or "continent/region".
You seem to be using this codes in an effort to manage the problem of DST, Daylight Saving Time. Leave such heavy-lifting to the date-time library, such as java.time or Joda-Time. A time zone combines an offset from UTC with the set of past, present, and future rules for DST and other anomalies. So you specify the time zone name and let the library do the work of figuring out when DST is in effect.
DST
Daylight Saving Time (DST) for Rome ends this year on October 25, 2015 at 3 AM. Clocks are rolled back to repeat the 2 AM hour. So there are two 2:30 times that day. You can see both of those 2:30 times in example code below.
2015-10-25T02:30+02:00[Europe/Rome]
2015-10-25T02:30+01:00[Europe/Rome]
Example Code
Here is some example code in java.time of Java 8 to see how DST is handled. First we take some "local" date-time, where "local" means without any particular time zone attached. We then assign the Rome time zone. After that we take the zoned values (the Rome values) and either add or subtract hours.
Ambiguity
Note how the notion of "2:30 AM in Rome" is meaningless on the 25th of October. You must know the offset of 01:00 or 02:00 to correctly interpret.
ZoneId zone = ZoneId.of( "Europe/Rome" );
System.out.println( "-----| Local |-----------------------------------------\n" );
LocalDateTime local_0130 = LocalDateTime.of( 2015 , Month.OCTOBER , 25 , 1 , 30 );
ZonedDateTime zoned_0130 = ZonedDateTime.of( local_0130 , zone );
LocalDateTime local_0230 = LocalDateTime.of( 2015 , Month.OCTOBER , 25 , 2 , 30 );
ZonedDateTime zoned_0230 = ZonedDateTime.of( local_0230 , zone );
LocalDateTime local_0330 = LocalDateTime.of( 2015 , Month.OCTOBER , 25 , 3 , 30 );
ZonedDateTime zoned_0330 = ZonedDateTime.of( local_0330 , zone );
System.out.println( "local_0130: " + local_0130 + " in zone: " + zone + " is " + zoned_0130 );
System.out.println( "local_0230: " + local_0230 + " in zone: " + zone + " is " + zoned_0230 );
System.out.println( "local_0330: " + local_0330 + " in zone: " + zone + " is " + zoned_0330 + "\n" );
System.out.println( "-----| Add Hours |-----------------------------------------\n" );
ZonedDateTime zoned_0130_plus_1H = zoned_0130.plusHours( 1 );
ZonedDateTime zoned_0130_plus_2H = zoned_0130.plusHours( 2 );
System.out.println( "zoned_0130_plus_1H: " + zoned_0130_plus_1H );
System.out.println( "zoned_0130_plus_2H: " + zoned_0130_plus_2H + "\n" );
System.out.println( "-----| Subtract Hours |-----------------------------------------\n" );
ZonedDateTime zoned_0330_minus_1H = zoned_0330.minusHours( 1 );
ZonedDateTime zoned_0330_minus_2H = zoned_0330.minusHours( 2 );
System.out.println( "zoned_0330_minus_1H: " + zoned_0330_minus_1H );
System.out.println( "zoned_0330_minus_2H: " + zoned_0330_minus_2H + "\n" );
When run.
-----| Local |-----------------------------------------
local_0130: 2015-10-25T01:30 in zone: Europe/Rome is 2015-10-25T01:30+02:00[Europe/Rome]
local_0230: 2015-10-25T02:30 in zone: Europe/Rome is 2015-10-25T02:30+02:00[Europe/Rome]
local_0330: 2015-10-25T03:30 in zone: Europe/Rome is 2015-10-25T03:30+01:00[Europe/Rome]
-----| Add Hours |-----------------------------------------
zoned_0130_plus_1H: 2015-10-25T02:30+02:00[Europe/Rome]
zoned_0130_plus_2H: 2015-10-25T02:30+01:00[Europe/Rome]
-----| Subtract Hours |-----------------------------------------
zoned_0330_minus_1H: 2015-10-25T02:30+01:00[Europe/Rome]
zoned_0330_minus_2H: 2015-10-25T02:30+02:00[Europe/Rome]
My advice is to use the full identifiers from the IANA time zone database. In your case you should be using "Europe/Rome":
before.setTimeZone(TimeZone.getTimeZone("Europe/Rome"));
This will make sure that proper time zone info is used for the region, including when daylight saving mode needs to be triggered, and possible regional exceptions.
Do not add DST.
"Europe/Rome" is not CET, and "Europe/Rome DST" is not CEST.
"Europe/Rome" is the timezone of Italy. It includes not only DST changes, but any other change to the offset that Rome/Italy has had. So "Europe/Rome" is CET when Rome is in CET and it's CEST when Rome is on CET. The whole point of timezones like "Europe/Rome" is that you don't have to care about daylight savings, the timezone will handle it for you.
I bumped into this issue today. I have set my clock to UTC-6.00 (Central America) time zone. I am converting the Date "06/01/2015::12:00:00 AM" ("MM/dd/yyyy::hh:mm:ss a" format) to a java Date object. And then I am reconverting the date object to String. There is a slight twist in how I am doing this though. I am listing the re conversion steps below -
Calculate UTC offset from current time zone. (-21600000)
Get all available timezone ids for this offset. (All have same offset)
Select the first time zone id. (Will have same offset)
Set this as the timezone.
Convert the date to string format using Java's Simple Date Format.
I see that the time now rendered is "06/01/2015::01:00:00 AM"
My questions :
Since the timezone offset is same during the creation and during conversion I expect the same time to be shown. But what I see is different. Why is it so?
Imagine the re conversion to be happening in the server and the creation to be happening in the client. I need to render back the same date and time to the client. How do I do this?
Please help! Any help is much appreciated.
EDIT : Following is the code. Note that I have set my current timezone to Central America.
public class TimeTest {
public static void main (String args[]) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy::hh:mm:ss a");
String dateInString = "01/06/2015::12:00:00 AM";
try {
Date date = formatter.parse(dateInString);
System.out.println("Before conversion --> " + formatter.format(date));
System.out.println("After conversion --> " + convertDateValueIntoString(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
private static String convertDateValueIntoString(Date dateValue){
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy::hh:mm:ss a");
String date;
int offset = TimeZone.getDefault().getRawOffset();
if (offset == 0) {
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
date = dateFormat.format(dateValue);
} else {
String TZ[] = TimeZone.getAvailableIDs(offset);
String timeZone = TZ[0];
if (timeZone == null) {
date = dateFormat.format(dateValue);
} else {
TimeZone tz = TimeZone.getTimeZone(timeZone);
dateFormat.setTimeZone(tz);
date = dateFormat.format(dateValue);
}
}
return date;
}
}
Why are the times different:
The difference appears to be in the handling of daylight savings time. Playing around with setting my machine to different time zones and printing the TimeZone toString() I ended up with:
Initial: sun.util.calendar.ZoneInfo[id="America/Tegucigalpa",offset=-21600000,dstSavings=0,useDaylight=false,transitions=9,lastRule=null]
Result: sun.util.calendar.ZoneInfo[id="America/Bahia_Banderas",offset=-21600000,dstSavings=3600000,useDaylight=true,...
Note that these two TimeZones have the same offset, but one uses daylight savings time and the other does not. The offset is all your code is looking at to find an appropriate TimeZone but the date formatting also uses the daylight savings offset.
How do I handle this:
The way every project I've been on that used times did it was to have all internal representation of time be in UTC (or a similar concept). I would have your client convert the time to UTC on input (before sending it to the server), have all server storage use UTC, then when times go back to the client have the client format to the default TimeZone only for output to the user.
That way all your internal times are consistent and all your displayed times are localized for the individual instance of the client, so a user in America/Tegucigalpa may get the time as 12:00 but the user in America/Bahia_Banderas would see 1:00. Both are correct for the users those times would be displayed to.
The Answer by 1337joe is correct. I'll add a few thoughts.
This Question has much confusion floating around.
Time Zone = Offset + Rules/Anomalies/Adjustments
First, a time zone is more than an offset from UTC. A time zone is an offset plus a set of past, present, and future rules about Daylight Saving Time and other anomalies & adjustments.
So whenever possible, use a named time zone rather than a mere offset. And certainly do not mix usage of offset-only with usage of time zones and expect sensible results. That seems to be the core problem in this Question.
So, dig deeper to discover the original intent of the programmers who devised your existing stored data. I suspect they did indeed have a particular time zone in mind rather than a mere offset.
Use Proper Time Zone Names
There is no such time zone as "Central America".
As 1337Joe points out, offsets and time zones vary around Central America. For example, America/Managua is six hours behind UTC while America/Panama is five.
By the way, avoid the 3-4 letter codes for time zones such as "EST" as they are neither standardized nor unique. The one exception is UTC of course.
Specify Your Expected/Desired Time Zone
When [a] you know your incoming data represents a particular time zone or offset, albeit implicitly, and [b] you desire a certain time zone to be applied, do not call on the default time zone. That is asking for trouble. The default time zone can vary by host OS setting on machine by machine. And both the host OS settings can be changed at any time by an admin person. Thirdly, the JVM’s current default time zone can be changed at any moment during runtime by a call to TimeZone.setDefault() by any code in any thread in any app in that same JVM.
So, instead of relying on the default time zone, specify the desired time zone.
Use UTC For Logic & Storage
As 1337joe said, your business logic, data storage, data communication, and database should all be in UTC (almost always). Only apply adjustments to local time zones when expected by the user/consumer.
In comments, the author said their project is already saddled with existing stored data implicitly representing a certain time zone or offset.
java.util.Date toString
The toString method on java.util.Date automatically applies the JVM’s current default time zone. This makes working with time zone adjustments tricky. One of many reasons to avoid using the java.util.Date/.Calendar & java.text.SimpleDateFormat classes.
Use Better Date-Time Library
Use either the new java.time package in Java 8 and later (Tutorial), or the Joda-Time library (which inspired java.time).
Joda-Time
Here is some example code in Joda-Time.
According to the author’s comments, the incoming string implicitly represents a date-time value for a certain known time zone. That time zone is not stated, so I'll arbitrarily use Panama time zone. In this first part, we parse a string while specifying the time zone to be used during parsing and assigned to the resulting object.
DateTimeZone zonePanama = DateTimeZone.forID( "America/Panama" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy::hh:mm:ss a" );
String input = "06/01/2015::12:00:00 AM";
DateTime dateTimePanama = formatter.withZone( zonePanama ).parseDateTime( input );
System.out.println( "Input as string: " + input + " becomes object: " + dateTimePanama + " with time zone: " + dateTimePanama.getZone() );
Now let's adjust to UTC. Here this is for demonstration. In real code you would generally do any further work using this UTC value.
DateTime dateTimeUtc = dateTimePanama.withZone( DateTimeZone.UTC );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
For output, our user/consumer expects a String representation in the same Panama time zone and in the same format as our input.
String output = formatter.print( dateTimeUtc.withZone( zonePanama ) );
System.out.println( "Output in special format: " + output );
When run.
Input as string: 06/01/2015::12:00:00 AM becomes object: 2015-01-06T00:00:00.000-05:00 with time zone: America/Panama
dateTimeUtc: 2015-01-06T05:00:00.000Z
Output in special format: 06/01/2015::12:00:00 AM
For question #1: The timezone offset may be the same for different timezones, but the DST may be used or not and this results in a difference.
For question #2:
For the future, you can only be safe about the time when you use UTC. (you can work around, if your time data is "recent" - see below)
For the past, you cannot reliably extract the correct time.
General conversion advice:
I worked on a project dealing with timezones and DST in a JDBC driver. There were problems storing time values and reading them back correctly. I worked /real hard/ trying to get a conversion right, so we could spare the larger works of switching to UTC. There is no correct conversion without UTC. ( /real hard/ : Think of Pulp Fiction where Jules says "I'm trying real hard to be the shepherd." :-) )
Question #2 / Future:
If your client cannot send UTC times (maybe because it is a third party system):
When your server receives time data (non UTC) from the client, which you know to be current within a few minutes (maybe somewhat longer), you could try to use your UTC time and match that to the client's time. Imagine your client sends "2015-06-01 15:45" and you know, it is now "2015-06-01 18:51 UTC", then you may interpret the client's time as "2015-06-01 18:45 UTC". If the time data sent by the client may be older than about an hour, this will fail in some cases.
Or in other words: Say your client records temperature values. If the data sent by the client is not older than a few minutes, you can match that to the UTC time. If your client records temperature of one day and sends you that at the end of the day, you cannot correctly match the time.
Why will you not be able to make a fully(!) correct conversion?
Assume the night when DST changes, so that the clock is changed from 03:00 back to 02:00. You have once 02:30 before the switch and another 02:30 after the switch. The first 02:30 has another UTC time than the second 02:30. So with UTC you are fine. But only with the "client local" 02:30, you will never be sure.
Back to the client data age: If your client sends data not older than a few minutes for 02:30 and then later another for the second 02:30, you can distinguish this on the server. If at 04:00 you get two records for 02:30, you cannot restore UTC any more.
Question #2 / Past:
Can you add a flag in the database so that new times which are transferred as UTC are marked "reliable" and the old values are not?
The output and the source:
The output from running the modified source on my system which has a TZ of "Europe/Berlin". Note that this has DST in use, but the first fetched TZ ("Algiers") has DST not in use.
formatter's TZ is sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
internal date value = 1433109600000 as UTC = 31/05/2015::10:00:00 PM
Before conversion --> 01/06/2015::12:00:00 AM
Conversion: offset != 0, using TZ sun.util.calendar.ZoneInfo[id="Africa/Algiers",offset=3600000,dstSavings=0,useDaylight=false,transitions=35,lastRule=null]
After conversion --> 31/05/2015::11:00:00 PM
Setting UTC...
formatter's TZ is sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
internal date value = 1433116800000 as UTC = 01/06/2015::12:00:00 AM
Before conversion --> 01/06/2015::12:00:00 AM
Conversion: offset != 0, using TZ sun.util.calendar.ZoneInfo[id="Africa/Algiers",offset=3600000,dstSavings=0,useDaylight=false,transitions=35,lastRule=null]
After conversion --> 01/06/2015::01:00:00 AM
The source code:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TimeTest {
static TimeZone utc = TimeZone.getTimeZone("UTC");
public static void main (String args[]) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy::hh:mm:ss a");
String dateInString = "01/06/2015::12:00:00 AM";
SimpleDateFormat utcformatter = new SimpleDateFormat("dd/MM/yyyy::hh:mm:ss a");
utcformatter.setTimeZone(utc);
try {
Date date = formatter.parse(dateInString);
System.out.println("formatter's TZ is " + formatter.getTimeZone());
System.out.println("internal date value = " + date.getTime() + " as UTC = " + utcformatter.format(date));
System.out.println("Before conversion --> " + formatter.format(date));
System.out.println("After conversion --> " + convertDateValueIntoString(date));
System.out.println("\nSetting UTC...\n");
formatter.setTimeZone(utc);
date = formatter.parse(dateInString);
System.out.println("formatter's TZ is " + formatter.getTimeZone());
System.out.println("internal date value = " + date.getTime() + " as UTC = " + utcformatter.format(date));
System.out.println("Before conversion --> " + formatter.format(date));
System.out.println("After conversion --> " + convertDateValueIntoString(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
private static String convertDateValueIntoString(Date dateValue){
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy::hh:mm:ss a");
String date;
int offset = TimeZone.getDefault().getRawOffset();
if (offset == 0) {
System.out.println("Conversion: offset == 0 -- setting UTC");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
date = dateFormat.format(dateValue);
} else {
String TZ[] = TimeZone.getAvailableIDs(offset);
String timeZone = TZ[0];
if (timeZone == null) {
System.out.println("Conversion: offset != 0, did not find TZ, tz of dateFormat is " + dateFormat.getTimeZone());
date = dateFormat.format(dateValue);
} else {
TimeZone tz = TimeZone.getTimeZone(timeZone);
System.out.println("Conversion: offset != 0, using TZ " + tz);
dateFormat.setTimeZone(tz);
date = dateFormat.format(dateValue);
}
}
return date;
}
}
http://www.oracle.com/technetwork/java/javase/tzdata-versions-138805.html
In above link of Oracle website they say that From version tzdata2014f, Java is supporting AEST/AEDT instead of EST for Australian timezone but I have current tzdata2014i version still it is not displaying EST only. Did I miss anything or is there anything do I need to do?
Here is small sample program I used ,
import java.util.*;
public class TZ {
public static void main(String[] args) {
System.out.println(System.getProperty("java.home"));
for (String id : TimeZone.getAvailableIDs()) {
if (!id.startsWith("Australia/")) continue;
TimeZone tz = TimeZone.getTimeZone(id);
System.out.println(id + ": " + "Daylight: False : " + tz.getDisplayName(false, TimeZone.SHORT) + "/" + " Daylight: True : "+ tz.getDisplayName(true, TimeZone.SHORT));
}
}
}
And here is my time zone datafile version
C:>java -jar tzupdater.jar -V
tzupdater version 1.4.9-b01
JRE time zone data version: tzdata2014i
Embedded time zone data version: tzdata2014i
Thanks in advance for any help.
Regards,
BennY
Your Question answers itself. As of tzdata2014f and later the A will be included:
Australian eastern time zone abbreviations are now AEST/AEDT not EST, and similarly for the other Australian zones. That is, for eastern standard and daylight saving time the abbreviations are AEST and AEDT instead of the former EST for both; similarly, ACST/ACDT, ACWST/ACWDT, and AWST/AWDT are now used instead of the former CST, CWST, and WST.
This change does not affect UTC offsets, only time zone abbreviations.
You say you are using tzdata2014i, which comes after tzdata2014f. So why are you confused about no longer seeing EST?
Time zone names
By the way, you should not be using these 3-4 letter abbreviations. They are not true time zones, not standardized, and not unique (as seen here with EST collision).
Instead use proper IANA time zone names in the format of continent/region. For example, Australia/Sydney.
Instant instant = Instant.now();
ZoneId zoneId = ZoneId.of( "Australia/Sydney" );
ZonedDateTime zdt = instant.atZone( zoneId );
instant.toString(): 2016-09-29T22:42:40.063Z
now.toString(): 2016-09-30T08:42:40.063+10:00[Australia/Sydney]
FYI, Wikipedia has a page about Time in Australia.
I have a String with local time:
"2012-12-12T08:26:51+000"
I now need to create a String with GMT time based on the old String. For example, assuming 2 hours difference between local and GTM:
"2012-12-12T10:26:51+000"
I have created a SimpleDateFormat:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSSS");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
String time = dateFormat.parse(mCreatedTime).toString();
But the time String is now in different format:
Wed Dec 12 etc
How do I get the output to be in format yyy-MM-dd'T'HH:mm:ss+SSSS but GMT time?
The dateFormat.parse() method returns an instance of Date, and when you call toString() on it the date will be printed in the default locale.
Use dateFormat.format() to get your Date value back to your required format.
As my comments on this question suggest, I believe the original poster of this question is confused and miseducated about date-time work. Nevertheless, I wrote some example code delivering exactly what Pierre asked for, along with my caveat that he is following some very bad practices.
Using Joda-Time 2.3 library and Java 7.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// CAUTION: The question asked specifically for the format used here.
// But this format incorrectly uses the PLUS SIGN to mean milliseconds rather than offset from UTC/GMT.
// Very bad thing to do. Will create no end of confusion.
// Another bad thing: This code creates strings representing date-times in different time zones without indicating they are in different time zones.
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
// "Atlantic/South_Georgia" is a time zone two hours behind UTC.
DateTimeZone southGeorgiaZone = DateTimeZone.forID( "Atlantic/South_Georgia" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MM-dd'T'HH:mm:ss+SSS" );
DateTime dateTimeInSouthGeorgia = formatter.withZone( southGeorgiaZone ).parseDateTime( "2012-12-12T08:26:51+000" );
DateTime dateTimeInUtc = dateTimeInSouthGeorgia.toDateTime( DateTimeZone.UTC );
String screwyBadPracticeDateTimeString = formatter.print( dateTimeInUtc );
System.out.println( "2012-12-12T08:26:51+000 in southGeorgiaDateTime: " + dateTimeInSouthGeorgia );
System.out.println( "same, in UTC: " + dateTimeInUtc );
System.out.println( "screwyBadPracticeDateTimeString: " + screwyBadPracticeDateTimeString );
When run…
2012-12-12T08:26:51+000 in southGeorgiaDateTime: 2012-12-12T08:26:51.000-02:00
same, in UTC: 2012-12-12T10:26:51.000Z
screwyBadPracticeDateTimeString: 2012-12-12T10:26:51+000