Even with about 15 years in Java one always stumbles over the topic of handling dates and times...
Here's the situation: I get a timestamp from some external system as a String representation. The timestamp's semantic is that it represents an UTC date. This timestamp has to be put in an entity and then into a PostgreSQL database in a TIMESTAMP field. Additionally I need to put the same timestamp as local time (in my case CEST) into the entity and then into the database in a TIMESTAMP WITH TIME ZONE field.
What is the right way to ensure that no matter what the settings of the machine executing the code are, the timestamps get stored correctly in the entity (to make some validations with other UTC timestamps) and in the database (to use them in reports later on)?
Here's the code, which worked fine on my local machine:
SimpleDateFormat sdfUTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utcTimestamp = sdfUTC.parse(utcTimestampString);
// getMachinesTimezone is some internal util method giving the TimeZone object of the machines Location
Calendar localTimestamp = new GregorianCalendar(getMachinesTimezone());
localTimestamp.setTimeInMillis(utcTimestamp.getTime());
But when executing the same code on the server, it resulted in different times, so I assume that it's not the correct way to handle it. Any suggestions?
PS: I read about Joda Time when searching in this forum, but in the given project I'm not able to introduce new libraries since I only change an existing module, so I have to live with the standard JDK1.6
If I understand correctly, You need to set the timezone on the same data/calendar object that you are printing. Like this:
private Locale locale = Locale.US;
private static final String[] tzStrings = {
"America/New_York",
"America/Chicago",
"America/Denver",
"America/Los_Angeles",
};
Date now = new Date();
for ( TimeZone z : zones) {
DateFormat df = new SimpleDateFormat("K:mm a,z", locale);
df.setTimeZone(z);
String result = df.format(now);
System.out.println(result);
}
if i set timezone to SimpleDateFormat it is working fine.
here is the sample code...
String date="05/19/2008 04:30 AM (EST)";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm aaa (z)");
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
long millis = sdf.parse(date).getTime();
sdf.setTimeZone(TimeZone.getDefault());
System.out.println(sdf.format(new Date(millis)));
I think you have to set the target time zone in you Calendar object. I think something like:
Calendar localTimestamp = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
localTimestamp.setTimeInMillis(utcTimestamp.getTime());
In other case Java takes the default system time zone for the Calendar instance.
You can do it by the below example code.
Date date = new Date();
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
Date date1 = dateformat.parse(formatter.format(date));
// Set the formatter to use a different timezone
formatter.setTimeZone(TimeZone.getTimeZone("IST"));
Date date2 = dateformat.parse(formatter.format(date));
// Prints the date in the IST timezone
// System.out.println(formatter.format(date));
Related
I am trying to get time (HH:MM) from below code in IST format but it still display UTC date, time.
Please help.
public static void main (String args[]) throws ParseException {
String date = "2021-07-05T14:17:00.000Z";
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
String timezoneID = timeZone.getID();
// Convert to System format from UTC
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date actualDate = format1.parse(date);
format1.setTimeZone(TimeZone.getTimeZone(timezoneID));
String date1 = format1.format(actualDate);
String time = date1.substring(11, 16);
String timezoneValue = TimeZone.getTimeZone(timezoneID).getDisplayName(false, TimeZone.SHORT);
String finalTime = time + " " + timezoneValue;
System.out.print(finalTime);
}
java.time
I strongly recommend that you use java.time, the modern Java date and time API, for your date and time work. Then your task becomes pretty simple. Rather than a formatter for your input format I want to define a formatter for your desired time format:
private static final DateTimeFormatter TIME_FORMATTER
= DateTimeFormatter.ofPattern("HH:mm zzz", Locale.ENGLISH);
Now the operation goes in these few lines:
String date = "2021-07-05T14:17:00.000Z";
String finalTime = Instant.parse(date)
.atZone(ZoneId.systemDefault())
.format(TIME_FORMATTER);
System.out.println(finalTime);
Output when I ran in Europe/Dublin time zone:
15:17 IST
Here IST is for Irish Summer Time. IST has several meanings, and I wasn’t sure which one you intended. Also many of the other popular time zone abbreviations are ambiguous. IST may also mean Israel Standard Time, but not here, since Israel uses Israel Daylight Time or IDT at this time of year. One other interpretation is India Standard Time used in India and Sri Lanka, So let’s try running the code in Asia/Kolkata time zone.
19:47 IST
I am exploiting the fact that your string is in ISO 8601 format, the format that the classes of java.time parse and also print as their default, that is, without any specified formatter.
What went wrong in your code?
Your bug is here:
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
You must never hardcode Z as a literal in your format pattern, which is what you are doing when enclosing it in single quotes. The Z is a UTC offset and needs to be parsed as such so that Java knows that your date and time are in UTC (which is what Z means). When you hardcode the Z, SimpleDateFormat understands the date and time to be in the default time zone of the JVM. So when afterward you try to convert into that time zone, the time of day is not changed. You’re converting into the time zone you already had. It’s a no-op.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Time Zone Abbreviations – Worldwide List
You are parsing the date using your default TimeZone, not UTC.
You never called format1.setTimeZone before parsing. A DateFormat uses the default timezone unless you set it to something else.
Let’s look at each line of your code:
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
That is getting the default TimeZone. You don’t need a Calendar object for that; just call TimeZone.getDefault().
String timezoneID = timeZone.getID();
There is no reason to call that. You already have a TimeZone object. Converting it to a string ID and back to a TimeZone is a pointless round-trip operation. So, you should remove all uses of timezoneID.
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
That is the problem. The DateFormat doesn’t treat the 'Z' as anything special; it’s just a literal character which the DateFormat knows not to parse.
You need to actually tell the DateFormat that it’s parsing a UTC time:
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
TimeZone utc = TimeZone.getTimeZone(ZoneOffset.UTC);
format1.setTimeZone(utc);
Date actualDate = format1.parse(date);
Instead of cutting out pieces of a formatted string, make a new DateFormat that does exactly what you want:
DateFormat timeFormat = new SimpleDateFormat("HH:mm z");
String finalTime = timeFormat.format(actualDate);
Since a SimpleDateFormat always uses the default TimeZone when it is created, there is no need to call this format object’s setTimeZone method.
I should mention that the java.time and java.time.format packages are much better for working with dates and times:
String date = "2021-07-05T14:17:00.000Z";
Instant instant = Instant.parse(date);
ZonedDateTime utcDateTime = instant.atZone(ZoneOffset.UTC);
ZonedDateTime istDateTime =
utcDateTime.withZoneSameInstant(ZoneId.systemDefault());
String finalTime = String.format("%tR %<tZ", istDateTime);
// Or:
// String finalTime = istDateTime.toLocalTime() + " "
// + itsDateTime.getZone().getDisplayName(
// TextStyle.SHORT, Locale.getDefault());
format1.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
is what you need since the 3-letter zone names are really deprecated. Plus:
String timezoneValue = format1.getTimeZone().getDisplayName(false, TimeZone.SHORT);
The method Calendar.getInstance() gets a calendar using the default time zone and locale - UTC±00:00.
Use "IST" instead of timeZone.getID().
Exemple:
String date="2021-07-05T14:17:00.000Z";
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
String timezoneID = "IST"; // <<<<<
// Convert to System format from UTC
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date actualDate = format1.parse(date);
format1.setTimeZone(TimeZone.getTimeZone(timezoneID));
String date1 = format1.format(actualDate);
String time = date1.substring(11, 16);
String timezoneValue = TimeZone.getTimeZone(timezoneID).getDisplayName(false, TimeZone.SHORT);
String finalTime = time + " " + timezoneValue;
System.out.print(finalTime);
I'm trying to convert milliseconds to Timestamp with timezone UTC but it doesn't work as is expected because it convert to my localdatetime.
I have tried following. While debugging the code I have found that when execute this: new DateTime(eventDate) it is working properly because it's value is 10:34:18.721 but later new Timestamp() change it to localdatetime.
long eventDate = 1566297258721L;
DateTimeZone.setDefault(DateTimeZone.UTC);
Timestamp timestamp = new Timestamp(new DateTime(eventDate).getMillis());
I expect to output as:2019-08-20 10:34:18.721 but actual output is: 2019-08-20 12:34:18.721
You can use java.time package of Java 8 and later:
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(1566817891743L).atZone(ZoneOffset.UTC);
I don't understand why you are creating a new DateTime and then get the milliseconds from there, if you already have the milliseconds in the beginning.
Maybe I'm misunderstanding your problem. The milliseconds have nothing to do with the timezone. The timezone is used to compare the same moment in 2 different places and get the respective date. Here are my solutions
If you want a timestamp from milliseconds:
long eventDate = 1566297258721L;
Timestamp time=new Timestamp(eventDate);
System.out.println(time);
The result would be 2019-08-20 10:34:18.721 , also the wished SQL format
If you want to convert a moment from a Timezone to another:
You will get the moment in your actual timezone and transform it in a different one in order to see e.g. what time it was in an other country
long eventDate = 1566297258721L;
Calendar calendar = Calendar.getInstance();
calendar.setTime(eventDate);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
dateFormat.format(calendar.getTime());
I hope those snippets could be useful. Happy Programming!
You can try the following,
long eventDate = 1566297258721L;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String stringDate = simpleDateFormat.format(new Date(eventDate));
System.out.println(stringDate);
It gives me the following output.
2019-08-20 10:34:18 UTC
I have a problem in displaying the date in my Application.
I am getting timestamp as:
2017-08-02T06:05:30.000Z
But as per this the actual time is:
2017:08:02 11:35 AM
But after converting using my code it displays the time as:
6:00 am
How to show it as current time?
My code is given below:
private static SimpleDateFormat timestampformat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.mmm'Z'");
private static SimpleDateFormat sdftimeformat = new SimpleDateFormat("HH:mm a");
private static SimpleDateFormat getSdftimeformat() {
return sdftimeformat;
}
public static String timeStampConvertToTime(String time) {
Date date1 = null;
try {
date1 = timestampformat.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
String formattedTime = getSdftimeformat().format(date1);
return formattedTime;
}
The first thing is that you're using mm:ss.mmm in your format. According to SimpleDateFormat javadoc, m represents the minutes, so you must change it to mm:ss.SSS because S represents the milliseconds.
Another detail is that the Z in the end is the timezone designator for UTC and it can't be ignored (at least it shouldn't). You must use the corresponding pattern for that, which is X:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
PS: the X pattern was introduced in Java 7. If you're using Java <= 6, the only alternative is to treat Z as a literal (an ugly workaround, I admit) and set the UTC as the timezone used by the parser:
// treat "Z" as literal
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// use UTC as timezone
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
With this, the date will have the value corresponding to 06:05 in UTC. To format the time to your timezone, you must use another SimpleDateFormat with the corresponding timezone:
// output format: hour:minute AM/PM
SimpleDateFormat outputFormat = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
// assuming a timezone in India
outputFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
System.out.println(outputFormat.format(date));
The output will be:
11:35 AM
If you don't set a timezone, it'll use the system's default. But the default can be changed without notice, even at runtime, so it's better to explicity set a specific timezone as above.
I also used java.util.Locale to set the language to English, because some locales can have different symbols for AM/PM. If you don't specify one, it'll use the system default and it's not guaranteed to be one in which the symbols are the ones you need (some locales uses "a.m./p.m." or another different formats, so it's better to use an explicit locale).
Java new Date/Time API
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.
If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).
The code below works for both.
The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.
To parse the input you can use the ZonedDateTime class, which has full support to timezones and it makes the conversion to another zones very easy. Then you use a DateTimeFormatter to format the output:
// parse the input
ZonedDateTime parsed = ZonedDateTime.parse("2017-08-02T06:05:30.000Z");
// convert to another timezone
ZonedDateTime z = parsed.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
// format output
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
System.out.println(fmt.format(z));
The output will be:
11:35 AM
If the input always has Z in the end, you can also use the Instant class:
// parse the input
Instant instant = Instant.parse("2017-08-02T06:05:30.000Z");
// convert to a timezone
ZonedDateTime z = instant.atZone(ZoneId.of("Asia/Kolkata"));
Note that I used hh for the hours: this will format using values from 1 to 12 (it makes sense because I'm also using the AM/PM designators). If you want values from 0 to 23, use HH instead - check the javadoc for more details.
Also note that the API uses IANA timezones names (always in the format Region/City, like Asia/Kolkata or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CST or IST) because they are ambiguous and not standard.
You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
You can also use the system's default timezone with ZoneId.systemDefault(), but this can be changed without notice, even at runtime, so it's better to explicity use a specific one.
You need to use SimpleDateFormat class and specify the format you want to parse from , like this :
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
long timeStamp = sdf.parse('your_timestamp').getTime();
SimpleDateFormat currentDateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm a", Locale.getDefault());
String time =currentDateFormat.format(timeStamp); // Formatted time in string form
try this your will get result
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss'Z'");
// set your format in df variable
SimpleDateFormat df = new SimpleDateFormat(
"HH:mm a");
try {
cal.setTime('your value');
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String localtime = df.format(cal.getTime());
use this for get current time.
Calendar cal =
Calendar.getInstance(TimeZone.getTimeZone("GMT+5:30"));
Date currentLocalTime = cal.getTime();
DateFormat date = new SimpleDateFormat("HH:mm a");
// you can get seconds by adding "...:ss" to it
date.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
String localTime = date.format(currentLocalTime);
change time zone to your time zone
I assume the Z in Rose's timestamp is zulu time, it isn't really correct to hard code the conversion from zulu time to his local time zone (GMT+5:30 we are assuming). It might be OK if it is always returning Z but if it is
military time zones you would need something that can handle all the possible timezones.
This previous question implies there is no built in way to do it. Need to understand where the timestamp is coming from to really answer the question.
I am getting a parse exception when trying to parse the time string 02:22 p.m..
I have the following conversion function:
public static long convertdatetotimestamp(String datestring, String newdateformat, String olddateformat){
SimpleDateFormat originalFormat = new SimpleDateFormat(olddateformat,Locale.ROOT);
SimpleDateFormat targetFormat = new SimpleDateFormat(newdateformat,Locale.ROOT);
Date date = null;
try {
date = originalFormat.parse(datestring);
String formattedDate = targetFormat.format(date);
Date parsedDate = targetFormat.parse(formattedDate);
long nowMilliseconds = parsedDate.getTime();
return nowMilliseconds;
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
The method is called in another activity with a time format "02:22 p.m.". olddateformat and newdateformat are the same: hh:mm a.
It causes following error in log:
java.text.ParseException: Unparseable date: "02:22 p.m." (at offset 6)
How to resolve this issue? Time is in exactly above mentioned format.
It so happens that a.m. and p.m. are called just this in Gaelic locale. At least on my Java 8. I am far from sure that it will be the case on (all) Android phones, but you may do some experiments with it.
String datestring = "02:22 p.m.";
Locale parseLocale = Locale.forLanguageTag("ga");
DateTimeFormatter originalFormat = DateTimeFormatter.ofPattern("hh:mm a", parseLocale);
System.out.println(LocalTime.parse(datestring, originalFormat));
This prints
14:22
As Hugo so warmly and rightly recommends is his answer, I am using the modern Java date and time API, so you will need ThreeTenABP for the above code. See How to use ThreeTenABP in Android Project. Alternatively you may want to try the same locale with your otherwise outdated SimpleDateFormat.
US Spanish locale shows the same behaviour on my Java 8, so you may try that too: Locale.forLanguageTag("es-US").
I believe that SimpleDateFormat can't be customized to parse the p.m. part (it only recognizes AM or PM).
So one alternative is to remove the dots:
String time = "02:22 p.m.";
SimpleDateFormat format = new SimpleDateFormat("hh:mm a", Locale.ROOT);
date = format.parse(time.replaceAll("\\.", ""));
One detail: to get the nowMilliseconds value, you need all the date fields (day/month/year) and a timezone. As those fields are not in the input String, SimpleDateFormat sets them to January 1st of 1970 (and also set the seconds and milliseconds to zero), and use the system's default timezone.
I'm not sure if this behaviour of getting January 1970 is consistent among all Java versions, which is another problem because you can get different values depending on the environment/device the code is running. Actually, you might have a different result anyway because it uses the system's default timezone and this can vary among different environments.
If I run this code in my machine, it uses my system's default timezone (America/Sao_Paulo), and the result is 62520000. But if I change the timezone to another (let's say, Asia/Kolkata), the result is 31920000. You must be aware of this variation and check if that's what you really need.
Another detail is that, if olddateformat and newdateformat are the same, there's no need to create 2 different formatters.
Java's new Date/Time API
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. You'll also need the ThreeTenABP (more on how to use it here).
All the relevant classes are in the org.threeten.bp package.
With this new API, you can customize the text that corresponds to AM/PM using a org.threeten.bp.format.DateTimeFormatterBuilder (so no need to remove the dots manually). And there are specific classes to each case - in this case, the input has only the time fields (hour and minutes), so I'm going to use the org.threeten.bp.LocalTime class (which represents only a time - hour/minute/second/nanosecond - without a date):
String time = "02:22 p.m.";
// map AM and PM values to strings "a.m." and "p.m."
Map<Long, String> map = new HashMap<Long, String>();
map.put(0L, "a.m.");
map.put(1L, "p.m.");
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// hour and minute
.appendPattern("hh:mm ")
// use custom values for AM/PM
.appendText(ChronoField.AMPM_OF_DAY, map)
// create formatter
.toFormatter(Locale.ROOT);
// parse the time
LocalTime parsedTime = LocalTime.parse(time, fmt);
The parsedTime variable will contain the values corresponding to 02:22 PM (and only this value, it has no date fields (day/month/year) nor a timezone).
To get the milliseconds value (number of milliseconds since 1970-01-01T00:00Z), you also need a date (day/month/year) and a timezone. As I said previously, those fields can affect the final value.
In the old API, SimpleDateFormat tries to be "smart" and sets default values for those fields (January 1st of 1970 in the system's default timezone), but the new API is more strict about that and you must tell explicity what date and timezone you want.
In this example, I'm using the Asia/Kolkata timezone but you can change it according to your needs (more on that below):
import org.threeten.bp.LocalDate;
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZonedDateTime;
// timezone for Asia/Kolkata
ZoneId zone = ZoneId.of("Asia/Kolkata");
// current date in Kolkata timezone
LocalDate now = LocalDate.now(zone);
// get the parsed time at the specified date, at the specified zone
ZonedDateTime zdt = parsedTime.atDate(now).atZone(zone);
// get the millis value
long millis = zdt.toInstant().toEpochMilli();
If you want a specific date instead of the current date, you can use LocalDate.of(2017, 5, 20) - this will get May 20th, 2017, for example. With this, you can set the code above to the date and timezone you need.
Note that the API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Asia/Kolkata).
Avoid using the 3-letter abbreviations (like IST or PST) because they are ambiguous and not standard.
You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
If you want to emulate exactly what SimpleDateFormat does, you can use LocalDate.of(1970, 1, 1) and use the default timezone with ZoneId.systemDefault() - but this is not recommended, because the system's default can be changed without notice, even at runtime. It's better to explicit what timezone you're using.
Or you can create a formatter that always sets default values for the date (using the org.threeten.bp.temporal.ChronoField class) and always uses the same timezone. So you can parse it directly to a org.threeten.bp.Instant and get the millis value:
String time = "02:22 p.m.";
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter fmt2 = new DateTimeFormatterBuilder()
// hour and minute
.appendPattern("hh:mm ")
// use custom values for AM/PM (use the same map from previous example)
.appendText(ChronoField.AMPM_OF_DAY, map)
// default value for day: 1
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
// default value for month: January
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
// default value for year: 1970
.parseDefaulting(ChronoField.YEAR, 1970)
// create formatter at my specific timezone
.toFormatter(Locale.ROOT).withZone(zone);
// get the millis value
long millis = Instant.from(fmt2.parse(time)).toEpochMilli();
Following changes that i've made works fine for me.
public static long convertdatetotimestamp(String datestring, String newdateformat, String olddateformat){
DateFormat originalFormat = new SimpleDateFormat(olddateformat,Locale.ENGLISH);
DateFormat targetFormat = new
SimpleDateFormat(newdateformat,Locale.ENGLISH);
Date date = null;
try {
date = originalFormat.parse(datestring.replaceAll("\\.", ""));
String formattedDate = targetFormat.format(date);
Date parsedDate = targetFormat.parse(formattedDate);
long nowMilliseconds = parsedDate.getTime();
return nowMilliseconds;
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
Locale.ENGLISH you can use your locale, english solved my issue. Reference.
Thanks for responses and references.
I need to create a java.util.Date object with an Australian timezone. this object is required for tag libraries used in downstream components (so I'm stuck with Date).
Here's what I have attempted:
TimeZone timeZone = TimeZone.getTimeZone("Australia/Sydney");
GregorianCalendar defaultDate = new GregorianCalendar(timeZone);
Date date = defaultDate.getTime();
However, "date" always returns the current local time (in my case, ET). What am I doing wrong here? Is it even possible to set a Date object with a different timezone?
Update:
Thanks for the responses! This works if I want to output the formatted date as a string, but not if I want to return a date object. Ex:
Date d = new Date();
DateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
String formattedDate = df.format(d); // returns Sydney date/time
Date myDate = df.parse(formattedDate); // returns local time(ET)
I think I'm going to end up reworking our date taglib.
Is it even possible to set a Date object with a different timezone?
No, it's not possible. As its javadoc describes, all the java.util.Date contains is just the epoch time which is always the amount of seconds relative to 1 january 1970 UTC/GMT. The Date doesn't contain other information. To format it using a timezone, use SimpleDateFormat#setTimeZone()
getTime is an Unix time in seconds, it doesn't have the timezone, i.e. it's bound to UTC. You need to convert that time to the time zone you want e.b. by using DateFormat.
import java.util.*;
import java.text.*;
public class TzPrb {
public static void main(String[] args) {
Date d = new Date();
System.out.println(d);
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
System.out.println(df.format(d));
df.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(df.format(d));
}
}