I am making a change to some code which runs on a unix box. It sets the time for a field in a database based on the current date and time for London.
The methods I am using are as follows;
private static Date getCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
format.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Calendar cal = Calendar.getInstance();
Date currentDate = cal.getTime();
try {
return format.parse(format.format(currentDate));
} catch (ParseException e) {
log.error("Error occured while parsing date-->" + e.getMessage());
}
return new Date();
}
private String getStringFromDate(Date date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-kk:mm:ss.SSS");
return sdf.format(date);
}
When the message is processed by the java app on the production unix box (which is set to north america time as thats where it is hosted) then when it is inserted into the database it is an hour behind (not being set to BST).
If I run the same code in Eclipse on my desktop, I get the correct time in the database.
I am unsure what might be causing this issue and was hoping someone might be able to help.
Thanks
edit*** at second glance, even the log files on the unix box are an hour behind so on that basis i assume its unix that is causing the issue opposed to my code.
A Date instance is always in UTC (or, it should be unless you've done something wrong). you should store your dates in the db in UTC and convert them to whatever timezone you desire when presenting them to the user. anything else is just asking for trouble.
your code which formats and then parses the Date instance in the same TimeZone is just meaningless.
tl;dr
A Date (and Instant) are always in UTC by definition. So no need to futz with time zone.
Instant.now() // Capture current moment in UTC.
Or, if you must use the troublesome legacy class Date:
java.util.Date.from( Instant.now() ) // Avoid the legacy classes whenever possible. When required, you can convert back-and-forth via new methods added to the old classes as seen here.
Always specify time zone
Never rely on the current default time zone of either your host OS or your JVM. That default value is out of your control and can change at any moment during runtime.
Instead:
Always use the java.time classes rather than the troublesome old legacy classes seen in your code.
Always specify your desired/expected time zone as an optional argument to the various java.time methods rather than rely implicitly on the JVM’s current default.
java.time
You appear to be trying to get the current moment as a java.util.Date object. That legacy class represents a value in UTC, so the time zone is irrelevant.
Instant
The modern replacement for that class is java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Capturing the current moment is simple: Instant.now.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
If you must have Date to inter-operate with old code not yet updated to java.time, convert by calling new methods added to the old classes.
java.util.Date javaUtilDate = java.util.Date.from( instant ) ;
Either way, be very aware that both a Date and an Instant represent a point on the timeline in UTC, always UTC.
UTC versus London Time
Also, be aware that UTC is not London time, a common misconception given that UTC/GMT is tracked from a point at the Royal Observatory, Greenwich. Actually, London has a history of anomalies in its offset-from-UTC, including the adoption of Daylight Saving Time (DST).
To get London time, assign a ZoneId to get a ZonedDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Europe/London" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, but viewed with a different wall-clock time used by the people of a particular region (time zone).
Generally, best practice is to keep your servers in UTC, and to do as much of your business logic, storage, and exchange of date-time values in UTC. Use a zoned value such as London time only when required either by business logic or presentation to user.
Notice in the code seen above that the current default time zone of any computer or JVM is irrelevant. A change in that default has no effect on your code.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
Other system send for us Timestamp in their time zone.If we run that in cloud in other system is +2 hours. Local is good because the server is the same time zone. How can I be sure that the time will always be right?
String TIME_STAMP_FORMAT = "yyyy-MM-dd-HH.mm.ss.SSSSSS";
DateTimeFormatter TIME_STAMP_FORMATTER = DateTimeFormatter.ofPattern(TIME_STAMP_FORMAT, Locale.getDefault());
private static Timestamp parseTimestamp(String dateString) {
try {
return Timestamp.valueOf(LocalDateTime.parse(dateString, TIME_STAMP_FORMATTER));
} catch (DateTimeParseException e) {
log.error("Not able to parse timestamp", e);
}
return null;
}
Date afterParse = parseTimestamp('2018-12-31-12.30.50.000200')
tl;dr
How can I be sure that the time will always be right?
Include an indicator of time zone or offset-from-UTC with your date-time input string.
Use standard ISO 8601 formats when exchanging date-time values.
Use only java.time classes in Java. Never use Date, Timestamp, Calendar, etc.
Tip: Adjust values from other zones to UTC before sending (generally speaking).
If not possible, then here is a workaround. This assumes you know the time zone intended by the sender of this poor data.
LocalDateTime // Represent a date and time-of-day without the context of a time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline. A meaningless value until you assign a zone/offset.
.parse(
"2018-12-31-12.30.50.000200" , // Avoid such custom formats. Use only ISO 8601 when exchanging date-time values textually.
DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) // Define formatting pattern to match youre input.
) // Returns a `LocalDateTime` object.
.atZone( // Give meaning to the `LocalDateTime` object by applying a time zone.
ZoneId.of( "Africa/Tunis" ) // Always specify a time zone with `Continent/Region` name, never the 2-4 character pseudo-zones popularly seen in the media.
) // Returns a `ZonedDateTime` object.
.toInstant() // Adjust from a time zone to UTC by extracting an `Instant` object. Same moment, same point on the timeline, different wall-clock time.
See this code run live at IdeOne.com.
Best to avoid java.util.Date class. But if you must interoperate with old code not yet updated to java.time, you can convert. Call on the new methods added to the old classes such as Date.from( Instant ).
Avoid legacy classes
Never use java.sql.Timestamp nor java.util.Date. All of the date-time classes bundled with the earliest versions of Java are now legacy, per the adoption of JSR 310. Use only the modern java.time classes.
Wrong data type
You are using the wrong data type. To track a moment, a specific point on the timeline, you must have a time zone or offset-from-UTC. The LocalDateTime class exactly the wrong class to use here. That class purposely lacks any concept of zone or offset. So it is the opposite of what you want.
To track a moment, use Instant, OffsetDateTime, or ZonedDateTime.
Where the java.time classes have methods with an optional time zone (ZoneId) or offset-from-UTC (ZoneOffset) argument, consider the argument required. Always pass a zone/offset. Then you never need worry about how the sysadmin is setting the JVM’s current default time zone at runtime.
ZonedDateTime.now( // Capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" )
)
Or, use Instant which is always in UTC, by definition.
Instant.now() // Capture the current moment in UTC.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ISO 8601
Your question is not clear, but it seems you are receiving an input string for a date-time in a custom format. I suggest you educate the people publishing that data about the ISO 8601 standard. This standard defines practical formats for date-time values being exchanged between systems textually.
The java.time classes use the ISO 8601 formats by default when parsing/generating strings.
Workaround
If the data publisher is sending you values such as 2018-12-31-12.30.50.000200 in order to communicate a moment, they have failed. A date and time-of-day without a zone or offset is useless, like communicating an amount of money without indicating a currency.
Do you know for certain the time zone that was implicitly assumed by the sender of this faulty data input? If so, apply it, as a clumsy stop-gap measure for their poor practice.
First parse your input as a LocalDateTime given that it lacks any indicator of zone/offset.
String input = "2018-12-31-12.30.50.000200" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Apply a ZoneId to get a ZonedDateTime object, thereby adjusting to view the moment through the wall-clock time used by the people of that particular region.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( ldt ) ;
Generally best to work with moments in UTC, unless you have a specific reason to use a time zone (such as presentation to user). So extract an Instant from your ZonedDateTime.
Instant instant = zdt.toInstant() ;
The Z at the end of an ISO 8601 compliant string means UTC, and is pronounced “Zulu”.
See this code run live at IdeOne.com.
input: 2018-12-31-12.30.50.000200
ldt: 2018-12-31T12:30:50.000200
zdt: 2018-12-31T12:30:50.000200+09:00[Asia/Tokyo]
instant: 2018-12-31T03:30:50.000200Z
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Just a small supplement to Basil Bourque’s clever and very informative answer.
I know the date is in CET timezone.
I am sorry, this is not enough. Central European Time (CET) is the common term for quite many European and African(!) time zones the details of which differ. The European ones are generally at offset +01:00 during standard time and at +02:00 during summer (known as Central European Summer Time or CEST). The African ones are at +01:00 all year. For past dates, just a few decades back, some zones used summer time (DST), others didn’t, some were at +00:00, +01:00 or +02:00, and further back in history many other offsets were used, generally not whole hours.
The future is even worse! It has been suggested that the European Union abandons summer time and leaves it to each member state whether they will use permanent standard time or permanent summer time, avoiding the time adjustments in spring and autumn. There is a power struggle going on about this, so we don’t know whether it will happen, nor what each member state chooses. So even if you could tell me the exact time zone of your string from the other system (for example, Europe/Sarajevo), no one knows yet whether 2019-11-01-00.30.50.000200 — less than 7 months from now — will be at offset +01:00 or +02:00.
Link: European MPs vote to end summer time clock changes on BBC News.
This code is working, but I want to use Joda-Time
public static Date dateFromUTC(Date date){
return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
}
I tried this, but it's not working - what's the problem with this?
public static Date dateFromUTC(Date date){
return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
}
tl;dr
Use java.time classes instead.
Instant.now() // Capture current moment in UTC. Always in UTC, by definition.
…and…
ZonedDateTime.now() // Capture current moment as seen through the wall-clock time of the people in the region of the time zone used by default in this JVM.
Details
As others said, you misunderstood the concepts involved in these classes. A java.util.Date represents a moment in UTC, always in UTC†, never in some other time zone. So the code seen in the Question is non-sensical. You are working too hard!
java.time
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. Many of the concepts are similar between Joda-Time and java.time as both projects are led by the same man, Stephen Colebourne.
When you are ready to migrate, use Instant in place of java.util.Date.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-01-23T12:34:56.123456789Z
Instead of java.util.Calendar, use ZonedDateTime to represent a moment seen through the wall-clock time of a particular region (a time zone).
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
As a shortcut, you can skip the Instant if you want only the zoned time.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen by people in a certain time zone.
You can get to UTC from there by extracting an Instant object.
Instant instant = zdt.toInstant() ; // Same moment, same point on the timeline, but viewed with the wall-clock time of UTC.
† Actually, there is a time zone assigned deep within a java.util.Date but is irrelevant to our discussion here. Confusing? Yes. One of many reasons to avoid the awful mess that is the old Date/Calendar and related legacy date-time classes.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Try this:
new DateTime(date, DateTimeZone.UTC)
.toLocalDateTime() // value without timezone
.toDateTime() // convert to default timezone
.toDate();
Your code actually does nothing to the date, because new DateTime(date) creates a DateTime object with default timezone. And then you just convert it back to java.util.Date.
First of all, read the article linked in the comments: https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
A java.util.Date doesn't have a timezone. It actually represents a point in time: the number of milliseconds since unix epoch (Jan 1st 1970, at midnight, in UTC).
When you print the Date, though, it uses the JVM default timezone to convert the Date to date/time values, but the Date itself doesn't have a timezone.
That's why converting a Date object to another timezone doesn't make sense.
If you want to know the date (day, month, year) and time (hour, minute, second, millisecond) that corresponds to the Date in a specific timezone, then you can use Joda-Time:
// java.util.Date
Date date = new Date();
// the Date converted to UTC
DateTime utc = new DateTime(date, DateTimeZone.UTC);
// the Date converted to JVM default timezone
DateTime convertedToDefaultTz= new DateTime(date, DateTimeZone.getDefault());
The conversion can also be made using another DateTime:
DateTime convertedToDefaultTz = utc.withZone(DateTimeZone.getDefault());
Joda's DateTime has a timezone attached to it, so now it makes sense to convert to another one. But the Date objects returned by it will always be the same, because all of them represent the same instant (the same point in the timeline):
Date d1 = utc.toDate();
Date d2 = convertedToDefaultTz.toDate();
System.out.println(d1.equals(d2)); // true
All because - again - a Date doesn't have a timezone.
I am attempting to show transactions over a certain time period using Jodatime.
Our server requires a start date and end date to be in UTC (which is probably obvious). Therefore any business logic around these is using DateTime object with the timezone set to DateTimeZone.UTC, e.g.
mStartDate = DateTime.now(UTC).withTimeAtStartOfDay();
That works well except when it comes to display the time I don't know how to augment it for the local (system default) timezone. Ideally I would like to use the DateUtils formatDateRange function passing in two local timestamps. But the getMillis() function doesn't seem to account for local offsets:
I have also tried this:
mTimePeriodTitle.setText(DateUtils.formatDateRange(mContext, f, mStartDate.getMillis(),
mEndDate.getMillis(), DateUtils.FORMAT_SHOW_TIME,
TimeZone.getDefault().getID()).toString());
But it hasn't made any difference. So my question is how can I get a nicely formatted local date range with 2 UTC timestamps?
If your DateTime is in UTC and you want to convert it to another timezone, you can use the withZone method to do the conversion.
For the examples below, my default timezone is America/Sao_Paulo (you can check yours using DateTimeZone.getDefault()):
// create today's date in UTC
DateTime mStartDate = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay();
// date/time in UTC
System.out.println(mStartDate); // 2017-06-13T00:00:00.000Z
// date/time in my default timezone (America/Sao_Paulo)
System.out.println(mStartDate.withZone(DateTimeZone.getDefault())); // 2017-06-12T21:00:00.000-03:00
The output is:
2017-06-13T00:00:00.000Z
2017-06-12T21:00:00.000-03:00
Note that the withZone method correctly converts the date and time to my timezone (in America/Sao_Paulo the current offset is UTC-03:00), so it was adjusted accordingly.
If you want to get just the time (hour/minute/second), you can use toLocalTime() method:
System.out.println(mStartDate.withZone(DateTimeZone.getDefault()).toLocalTime()); // 21:00:00.000
The output is:
21:00:00.000
If you want another format (for example, don't print the 3 digits of fraction-of-second), you can use a DateTimeFormatter. The good thing is that you can set a timezone in the formatter, so you don't need to convert the DateTime:
// create formatter for hour/minute/second, set it with my default timezone
DateTimeFormatter fmt = DateTimeFormat.forPattern("HH:mm:ss").withZone(DateTimeZone.getDefault());
System.out.println(fmt.print(mStartDate)); // 21:00:00
The output is:
21:00:00
To get your range, you can use one of the methods above with your DateTime's (mStartDate and mEndDate), and use the DateTimeFormatter to change to whatever format you need.
PS: what I think you're missing when using getMillis() is that both datetimes (in UTC and in default timezone) represents the same instant. You are just converting this instant to a local time, but the millis is the same (think that, right now, at this moment, everybody in the world are in the same instant (the same millis), but their local times might be different depending on where they are). So, when converting a UTC DateTime to another timezone, we're just finding what is the local time in that zone, that corresponds to the same millis.
You can check this using the getMillis() method on both objects:
System.out.println(mStartDate.getMillis()); // 1497312000000
System.out.println(mStartDate.withZone(DateTimeZone.getDefault()).getMillis()); // 1497312000000
Note that, even if I convert the object to another timezone, the millis remains the same (1497312000000). That's because both represent the same instant, I'm just moving them to another timezone where the respective local time is different.
Java new Date/Time API
Joda-Time it's being discontinued and replaced by the new APIs, so I don't recommend start a new project with it. If that's your case, you can consider using the new Date/Time API, but if you have a big codebase using Joda or don't want to migrate it now, you can desconsider the rest of the answer.
Anyway, even in joda's website it says: "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).".*
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. I'm not sure if it's already available to all Android versions (but see the alternative below).
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 a way to use it, with 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 get the current date at start of the day in UTC, you can do:
// UTC's today at start of the day
ZonedDateTime utc = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC);
System.out.println(utc); // 2017-06-13T00:00Z
First I did LocalDate.now(ZoneOffset.UTC) to find the current local date in UTC. If I use just LocalDate.now(), it'll get the current date in my default timezone, which is not what we want (it might be different from UTC, depending on where - and when - you are and what the default timezone is).
Then I used atStartOfDay(ZoneOffset.UTC) to get the start of the day at UTC. I know it sounds redundant to use UTC twice, but the API allows us to use any timezone in this method, and IMO it makes explicit what timezone we want (if the date is in a timezone with Daylight Saving changes, the start of day might not be midnight - the timezone parameter is to guarantee that the correct value is set).
The output is:
2017-06-13T00:00Z
To convert to my default timezone, I can use ZoneId.systemDefault(), which in my case returns America/Sao_Paulo. To convert it and get only the local time part, just do:
System.out.println(utc.withZoneSameInstant(ZoneId.systemDefault()).toLocalTime()); // 21:00
The output is:
21:00
If you want to change it, you can also use a formatter:
// formatter for localtime (hour/minute/second)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(fmt.format(utc.withZoneSameInstant(ZoneId.systemDefault()))); // 21:00:00
The output is:
21:00:00
java.time
The Joda-Time project is now in maintenance mode, with the project advising migration to the java.time classes.
Zones
Our server requires a start date and end date to be in UTC (which is probably obvious).
Yes, use UTC for much of your business logic, as well as for logging, storing, and exchanging date-time values. Think of UTC as the One True Time, with other zones being mere variations. Apply a time zone only when required for specific rules in your business logic or for presentation to the user.
For a value in UTC, use Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture the current moment in UTC.
To see the same moment in a particular time zone, assign a ZoneId to get a ZonedDateTime object. Same moment, same point on the timeline, different wall-clock time.
ZoneId zTunis = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdtTunis = instant.atZone( zTunis ) ;
See the same moment in yet another zone.
ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtAuckland = instant.atZone( zAuckland );
Strings
So my question is how can I get a nicely formatted local date range with 2 UTC timestamps?
After making the adjustments from UTC to a time zone as shown above, generate strings to represent their value.
To generate a String representing any of those objects in standard ISO 8601 format, simply call toString.
String output = instant.toString() ;
2018-01-23T01:23:45.123456Z
String output = zdtAuckland.toString() :
2018-01-23T14:23:45.123456+13:00[Pacific/Auckland]
To generate a String in other formats, define a formatting pattern. Or let java.time automatically localize.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );
mardi 23 janvier 2018 à 14:23:45 heure avancée de la Nouvelle-Zélande
Note that time zone has nothing to do with Locale. One is for content, the other is for presentation.
Interval
When representing a pair of moments, a couple of start-stop moments, use the Interval class found in the ThreeTen-Extra library (linked below). This class represents a pair of Instant objects.
Its toString method generates a string is standard ISO 8601 format. For other formats, and for adjustments into other zones, use the code seen above to apply to each Instant a ZoneId to generate a ZonedDateTime. Access each Instant via getStart & getEnd.
Interval interval = Interval.of( start , stop ) ;
interval.toString(): 2007-12-03T10:15:30/2007-12-04T10:15:30
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone.
If I run Date command in terminal it return date in CEST Zone time - this is perfect.
But In Java if I run the following code
System.out.println (new Date ());
It returns me time in EDT. What configuration am I missing.
You have to be careful in interpreting date objects from the display you get in console because they are formatted using the default TimeZone of the VM on which this program is running (which by default inherits it from timezone of OS).
Of course you can supply your own TimeZone as explained in the answer by Jesper. But while doing so I would strongly recommend to use IANA timezone identifiers like America/New_York instead of EST. More so because abbreviations having "standard" do not take into account day light savings.
So if you simply print the date object on console and you are not getting expected result, chances are high that you have your server timezone is set to wrong value or your OS is set at wrong timezone.
For changing the JVM timezone you can use this parameter on startup
-Duser.timezone="America/New_York"
You say the server is configured to be in the CEST timezone, but according to Java the default timezone is EDT. Java gets the default timezone from the operating system, so probably your server is not properly set to be in CEST.
If you want to print the date in a specific timezone, use a DateFormat and set the timezone on it:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println(df.format(new Date()));
Note: CEST is not a valid timezone according to my Java (Java 7u45). Did you mean "CET"? (CEST is the summertime variant of CET, but if you use CET, Java will automatically display the time in summertime if appropriate).
tl;dr
UTC:
Instant.now() // Instantiate an object capturing the current moment in UTC.
.toString() // Generate a String representing textually that date-time value using standard ISO 8601 format.
2018-03-16T00:57:34.233762Z
Zoned:
ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) // Instantiate an object representing the current moment with a wall-clock time seed by people in a particular region (time zone).
.toString() // Generate a String representing textually that date-time value using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets.
2018-03-16T01:57:34.233762+01:00[Africa/Tunis]
Details
The Answer by Shailendra is spot-on correct.
In addition, the Date class seen in the Question is part of the troublesome old date-time classes that are now legacy, supplanted entirely by the java.time classes.
The replacement for java.util.Date is java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant::toString ➞ UTC always
When calling the legacy class’ Date::toString method, the unfortunate behavior chosen by its authors is to dynamically apply your JVM’s current default time zone. This creates no end of confusion. Fortunately, the modern class tells the simple truth without adding any time zone: An Instant is always in UTC.
Instant.now().toString()
2018-03-16T00:57:34.233762Z
That strings format is standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.
CEST Zone time
There is no such thing as a time zone named CEST. Such 3-4 letter names are pseudo-zones. They are not standardized. They are not unique(!). Instead use a proper time zone in format of continent/region.
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
You can adjust from UTC to such a time zone by applying a ZoneId to your Instant to get a ZoneDateTime.
Instant instant = Instant.now() ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-03-16T01:57:34.233762+01:00[Europe/Paris]
Or use the shortcut, ZonedDateTime.now.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
You can adjust a ZonedDateTime to another time zone as well. Notice that java.time uses immutable objects. So in adjusting we get a new distinct object based on the original but without disturbing the original.
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;
zdtNewYork.toString(): 2018-03-15T20:57:34.233762-04:00[America/New_York]
Be very clear that instant, zdt, and zdtNewYork are three separate objects that represent the very same moment, the same point on the timeline. Same moment, different wall-clock time.
I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone
FYI, generally speaking, the best practice for a server’s default time zone is UTC.
More importantly, the current default time zone of your server OS and JVM should be irrelevant to your Java app.
Rather than rely implicitly on the JVM’s current default time zone, always specify explicitly the desired/expected time zone. Pass the optional ZoneId argument to the various java.time methods as seen in the code above.
(By the way, ditto for Locale - always specify desired/expected locale rather than rely implicitly on current default.)
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This may be a very basic question, but i could'nt find any satisfactory answers.Hope my doubts gets clear on stackoverflow.
Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Q 2. Is there any way to get timezone using JavaScript?
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
possible duplicate link
Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
Create a formatter and set the timezone in there.
Internally, java.util.Date just stores milliseconds since the Epoch in the UTC timezone.
When you use Date.toString() or new SimpleDateFormat() without a timezone, then the default timezone of your VM is used.
So in a sense, Java always converts to your current/default timezone (unless you happen to be in UTC).
Is there any way to get timezone using Java Script?
It depends. You can use getTimezoneOffset() but that gives you only the offset. There is no API to get the client's OSs timezone ID (like UTC, Europe/Berlin, etc.)
A timezone is just the representation of time...
Not really. See above.
Q 1. Suppose i have time in a different timezone and i want to convert it to a different timezone, what is the way to do it in Java?
The modern way is with the java.time classes.
Firstly, do much of your work in UTC. Apply a time zone only where necessary, such as presentation to a user.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
If you have only an offset-from-UTC rather than a time zone, apply a ZoneOffset to get a OffsetDateTime.
ZoneOffset offset = ZoneOffset.ofHours( -4 );
OffsetDateTime odt = instant.atOffset( offset );
A time zone is an offset-from-UTC (a specific number of hours, minutes, and seconds) plus a set of rules for handling anomalies such as Daylight Saving Time (DST). Represent a time zone with a ZoneId object. Specify a proper time zone name. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
Apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
You can apply other time zones to either the Instant or the ZonedDateTime.
ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );
Q 2. Is there any way to get timezone using JavaScript?
The issue of determining a time zone from a web browser has been handled countless times on Stack Overflow already.
So I'll skip this, except to say the upshot: No, not really in a reliable way; When important to know the time zone precisely you must ask the user herself.
Q 3. A timezone is just the representation of time in a particular zone, but actually every zone is at the same time,just representation wise it may be different depending on geographical conditions. - Is this understanding Correct?
No, a time zone is not a date-time moment.
A time zone adds meaningful context to a date-time in the same way that a currency designation adds meaningful context to an amount of money. A date-time without a time zone is just a rough idea of possible moments, not a precise point on the timeline. Noon at Auckland is earlier than noon in Kolkata which is earlier than noon in Paris which is earlier than noon in Montréal Québec.
You can think of it as pseudo-math statement:
Time Zone = ( Offset-from-UTC + set-of-rules-for-anomalies )
An example of an imaginary time zone:
An offset might be “one hour ahead of UTC”, plus
This set of rules: “On this date we will engage DST, on this date we will disengage DST, on this date during World War II we did shift ahead one hour, on this date after World War II we shifted back one hour, on this date our government shifted clocks forward a half-hour to make us distinct from our arch-rival neighbor country, …”.
You can apply a time zone to a point on the timeline. Like looking at art through a lens, it changes your perception but not the artifact itself. Looking at a point on the timeline through the lens of a time zone distorts the time-of-day and possibly the date into that of a particular community’s wall-clock time.
Another pseudo-math equation as a way of thinking about the class representations of a time zone and a moment on the timeline:
ZonedDateTime = Instant + ZoneId
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I can answer to your second question and correct the Aaron Digulla very complete response
Is there any way to get timezone using Java Script?
try to use this library, it will return a TimeZone ID with particular limitation (menthioned in the developer's page):
https://bitbucket.org/pellepim/jstimezonedetect