How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.
Related
I have a java.sql.Date object and want to transform it to a java.time.LocalDateTime object.
For comparison, I am able to do a similar transformation using java.util.Date:
java.util.Date utilDate = new java.util.Date(sqlDate.getTime());
System.out.println("date with time: " + utilDate);
This answer doesn't work for me, as my java.sql.Date does not have a getTimestamp method.
For reference, this question addresses the opposite transformation.
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Do not use java.sql.Date
Do not use java.util.Date
Do not use java.sql.Timestamp
Do not use java.util.Calendar
Use only java.time classes.
For exchanging date-time values with a database, use JDBC 4.2 or later.
The java.sql.Date class pretends to represent a date-only value.
If you are handed a java.sql.Date object, immediately convert it to a java.time.LocalDate. Use the new method toLocalDate added to that old class.
LocalDate localDate = myJavaSqlDate.toLocalDate() ;
You asked for a java.time.LocalDateTime object. You have the necessary date portion. Now you need to assign the time-of-day portion.
LocalTime localTime = LocalTime.of( 15 , 30 );
Combine.
LocalDateTime localDateTime = LocalDateTime.of( localDate, localTime ) ;
A LocalDateTime is inherently ambiguous. 3:30 PM 🕞 in Japan 🇯🇵 is a different moment than 3:30 PM 🕞 in Morocco 🇲🇦.
To determine a moment, a specific point on the timeline, place your LocalDateTime within the context of a time zone. You get a ZonedDateTimeObject.
ZoneId zoneId = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zonedDateTime = localDateTime.atZone( zoneId ) ;
To view that moment as seen in UTC, with an offset from UTC of zero hours-minutes-seconds, extract an Instant.
Instant instant = zonedDateTime.toInstant() ;
To answer your question as asked
There’s a wealth of good information in the clever answer by Basil Bourque. Not least the recommendation to avoid the java.sql.Date class completely so you won’t need the conversion.
For this answer I am assuming that you are getting a java.sql.Date from a legacy API that you can’t afford to upgrade to java.time just now. So you do need some conversion, and you have reasons to ask for a LocalDateTime representing the time in the default time zone of the JVM (a fragile practice). There is still a question to consider: do you want only the date part of the Date, or its point in time? Asking because a java.sql.Date was meant for representing a date without time of day, but the API does not enforce this, and a java.sql.Date holds a point in time with millisecond precision. I hope we already told you that this is a confusing class better to be avoided if you can.
To get the start of the day:
java.sql.Date oldfashionedSqlDate
= java.sql.Date.valueOf(LocalDate.of(2021, Month.OCTOBER, 26));
System.out.println("java.sql.Date: " + oldfashionedSqlDate);
LocalDateTime dateTime = oldfashionedSqlDate.toLocalDate().atStartOfDay();
System.out.println("LocalDateTime: " + dateTime);
Output (assuming the default time zone of the JVM has not changed in the meantime):
java.sql.Date: 2021-10-26
LocalDateTime: 2021-10-26T00:00
To get the point in time: To pick up the full precision held in the Date object:
java.sql.Date oldfashionedSqlDate = new java.sql.Date(1_666_000_000_000L);
System.out.println("java.sql.Date: " + oldfashionedSqlDate);
long epochMilli = oldfashionedSqlDate.getTime();
LocalDateTime dateTime = Instant.ofEpochMilli(epochMilli)
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
System.out.println("LocalDateTime: " + dateTime);
Output in my time zone:
java.sql.Date: 2022-10-17
LocalDateTime: 2022-10-17T03:46:40
Since the conversion is time zone dependent, output in other time zones will differ in most cases.
How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.
I have several time zone strings in UTC format, such as "UTC+08:00", "UTC-05:00", the question is how can i convert these utc format strings to the java.util.TimeZone in Java?
I have tried to convert by ZoneId as follows, but it did not work:
ZoneId zoneId = ZoneId.of("UTC+08:00");
TimeZone timeZone = TimeZone.getTimeZone(zoneId);
I know TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai"); would work, but I do not know the mapping between "UTC+08:00" and "Asia/Shanghai"
tl;dr
Do not use TimeZone class (now legacy).
Use ZoneOffset and ZoneId instead.
Example:
ZoneOffset.of( "+08:00" )
Use java.time.ZoneId, not TimeZone
The troublesome old date-time classes bundled with the earliest versions of Java are now legacy, supplanted by the java.time classes. Among these old legacy classes is TimeZone, now supplanted by ZoneId and ZoneOffset.
An offset-from-UTC is a number of hours and minutes adjustment ahead of, or behind, UTC. This is represented by the ZoneOffset class.
A time zone is a collection of offsets, the history of changes in the offset used by a particular region in determining their wall-clock time. This is represented by the ZoneId class.
Using a time zone is always preferable to an offset as a zone has the offset plus so much more information. But your examples are only mere offsets. So use the ZoneOffset to parse the strings after deleting the characters UTC.
String input = "UTC+08:00".replace( "UTC" , "" ) ;
ZoneOffset offset = ZoneOffset.of( input ) ;
Do not guess the time zone
You cannot assume that a particular offset implies a particular time zone. Many zones may have used a particular offset in the past, present, or future. So you should not guess the zone.
Take, for example, the offset of +08:00. That offset is currently used by several different time zones including Asia/Shangai, Asia/Macao, and Australia/Perth.
If you are certain a particular zone was intended for a date-time value, apply it to get a ZonedDateTime. But do not guess.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now() ;
ZoneId z = ZoneId.of( "Asia/Shanghai" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
If you do not know for certain the intended time zone and have only an offset, use the offset to get an OffsetDateTime.
Instant instant = Instant.now() ;
ZoneOffset offset = ZoneOffset.of( "+08:00" ) ;
OffsetDateTime odt = instant.atOffset( offset ) ;
Convert
Best to avoid the old legacy class TimeZone. But if you must use that class to work with old code not yet updated for the java.time classes, you can convert to/from a ZoneId. Use the new conversion methods added to the old classes.
TimeZone myLegacyTimeZone = TimeZone.getTimeZone( myModernZoneId );
…and…
ZoneId z = myLegacyTimeZone.toZoneId() ;
Note that ZoneOffset is a subclass of ZoneId. Normally, we ignore that inheritance relationship. If you have only a mere offset such as +08:00, use ZoneOffset. If you have a full time zone such as Asia/Shanghai, use ZoneId. One exception to this rule is for this conversion to/from TimeZone where only the superclass ZoneId is recognized.
If you strip the UTC, you can parse it as a ZoneOffset, which extends ZoneId
ZoneId zoneId = ZoneOffset.of("+08:00")
Since you can use the modern classes in the java.time package, I recommend you stick with them and avoid the outdated classes like TimeZone, SimpleDateFormat and Date. I am mostly repeating what #Basil Bourque already said in his answer, but also wanted to demonstrate how nicely his suggestion fits into your context:
DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm");
ZonedDateTime dateTime = LocalDateTime.parse(dateTimeString, format).atZone(zoneId);
Instant i = dateTime.toInstant();
System.out.println(dateTime + " -> " + i);
I have also demonstrated that you may convert the ZonedDateTime to an Instant in case you need that. The snippet prints
2017-05-05T05:05+08:00[UTC+08:00] -> 2017-05-04T21:05:00Z
If you are sure your date-time string and your zone string belong together, there is no need to go through String.replace() for removing UTC from the beginning of the zone string.
I am parsing the string independently of the time zone and then combining it with the zone offset information afterward. I think it’s more natural than having to know the zone for parsing.
In case you need an oldfashioned Date, for example for a call to some legacy code, that’s easy enough:
Date d = Date.from(i);
The old classes are troublesome
Even though I know the old classes have a tendency to show unwanted behaviour without telling you that anyting is wrong, I was still negatively surprised to learn that the code in your question didn’t work. It gives a time zone of GMT! It’s documented that this is a possibility, though, in the documentation of TimeZone.getTimeZone(ZoneId):
Returns:
the specified TimeZone, or the GMT zone if the given ID cannot be understood.
One may stil wonder how a simple time zone like UTC+08:00 can be “not understood”.
In the code below I have used calendar object to initialize time Zone to GMT and get the time accordingly but when I put back in date object, its automatically converting to my local time zone i.e. IST.
Calendar gmt = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dt=gmt.getTime();
Could anyone suggest a way through which I can retain the GMT format in date object also.
its automatically converting to my local time zone i.e. IST
No it's not. A Date object doesn't have a time zone - it's just an instant in time.
You'll see the system-local time zone if you call toString() on a Date, because that's unfortunately what Date.toString() does... but the time zone is not part of the information stored in a Date.
If you want to see a textual representation of a Date in a particular time zone, use DateFormat and set the time zone that you want to use.
java.time
The other answers are correct. The toString method silently applies your JVM’s current default time zone. This is one of many poor design choices in the old date-time classes. Dump those old classes. Move on to the java.time framework built into Java 8 and later.
An Instant is a moment on the time line in UTC.
Instant now = Instant.now();
Apply a time zone (ZoneId) to an Instant to get a ZonedDateTime.
Why are we bothering to create a ZonedDateTime in UTC if the Instant is already in UTC? Because a ZonedDateTime gives you flexibility in formatting String representations of the date-time values. The java.time.format package does not work with Instant objects.
A subclass of ZoneId, ZoneOffset, has a constant for UTC.
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant( ZoneOffset.UTC );
Adjust into any desired time zone.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = ZonedDateTime.ofInstant( instant , zoneId );
Use proper time zone names
Avoid using 3-4 letter codes for time zones. They are neither standardized nor unique. By IST did you mean India Standard Time or Irish Standard Time?
Use standard time zone names. Most are in the pattern of continent/region. For India, Asia/Kolkata. For Ireland, Europe/Dublin.
The Date class does not represent a timezone. It's toString method uses the default platform time zone to output a human readable timestamp, internally it's just a long.
I have been searching over the net from past few hours to get the datetime in my system timezone.
When I use calendar.getTimezone.getDefaultName()it always returns me GMT. Ideally it should return my current timezone, which is IST.
I am trying to convert this string "2014-02-14T06:04:00:00", which is in GMT to my timezone datetime. It always returns me the same time in GMT.
All I see is that everyone is suggesting to use Timezone, i.e,
dateFormatter.setTimezone("any_arbitary_timezone");
Point is my application will be used in different geographical locations. I cannot set it to a particular timezone. It should be set to the system timezone, so that it can display in whichever timezone the user is currently in.
tl;dr
Use the modern java.time classes.
ZonedDateTime.now( // Capture the current moment in the wall-clock time used by the people of a certain region (a time zone).
ZoneId.systemDefault() // Get the JVM’s current default time zone. Can change at any moment during runtime. If important, confirm with the user.
) // Renders a `ZonedDateTime` object. To see the same moment in UTC, extract a `Instant` object by calling `ZonedDateTime::getInstant`.
You may omit the explicit call to ZoneId.systemDefault. (But I do not recommend this.)
ZonedDateTime.now() // Capture the current moment in the JVM’s current default time zone.
Parse your string as a LocalDateTime, and adjust into desired time zone.
LocalDateTime.parse( "2014-02-14T06:04:00:00" ) // Parse a string lacking any indicator of time zone or offset-from-UTC. *Not* a specific point on the timeline.
.atOffset( ZoneOffset.UTC ) // Apply UTC as we are certain that offset-from-UTC of zero was intended by the supplier of that input string. Returns a `OffsetDateTime` object.
.atZoneSameInstant( // Adjust into another time zone. The `sameInstant` part means the same moment, different wall-clock time.
ZoneId.of( "Africa/Tunis" ) // Specify the particular zone of interest to you.
) // Returns a `ZonedDateTime` object.
Avoid java.util.Date & .Calendar
These legacy classes are notoriously troublesome. Sun/Oracle added the java.time package in Java 8 to supplant them. That package was inspired by Joda-Time.
Amongst the legacy classes’ problems is this confusing behavior: While a java.util.Date has no time zone information, it's toString implementation applies the JVM’s current default time zone when generating a String. So it misleads you by seeming to have a time zone when it does not.
java.time
I am trying to convert this string "2014-02-14T06:04:00:00", …
Your input string lacks any indicator of time zone or offset-from-UTC. So we parse as a LocalDateTime, which lacks any concept of zone/offset.
A LocalDateTime does not represent a moment, is not a point on the timeline. The word “Local” here does not mean a specific locality. It means “no specific locality at all”. Without the context of a zone/offset, it has no real meaning.
LocalDateTime ldt = LocalDateTime.parse( "2014-02-14T06:04:00:00" ) ;
… which is in GMT …
You say you are certain the supplier of that input string intended UTC as the context. We can apply an offset-from-UTC of zero, or UTC itself, to get an OffsetDateTime object. An OffsetDateTime is a moment, a point on the timeline. We can specify the ZoneOffset using the constant for UTC, ZoneOffset.UTC.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
… to my timezone datetime
Apparently you want to adjust that moment into another time zone, to see the wall-clock time used by the people of a particular region. We need to apply a time zone (ZoneId) to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZone( z ) ;
Instead of specifying a time zone, you can ask your JVM for its current default time zone. Beware: The JVM’s current default time zone can be changed at any moment by any code in any thread of any app within that JVM.
ZoneId z = ZoneId.systemDefault() ;
ZonedDateTime zdt = odt.atZone( z ) ;
Point is my application will be used in different geographical locations.
Simply specify your desired/expected time zones explicitly. This is always good practice, in my opinion. The default time zone lies outside your control as a programmer, which makes it unreliable.
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(!).
Another tip: Work, think, store, and exchange in UTC. Forget about your own parochial time zone, as translating back-and-forth to your home zone will drive you batty. Think of UTC as the One True Time, and other zones/offsets are but mere variations.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtAuckland = instant.atZone( zAuckland ) ;
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = instant.atZone( zKolkata ) ;
ZoneId zCasablanca = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdtCasablanca = instant.atZone( zCasablanca ) ;
There we have four ways ( instant, zdtAuckland, zdtKolkata, zdtCasablanca ) of looking at the very same simultaneous moment, the same point on the timeline.
instant.toString(): 2018-05-08T20:55:14.761721Z
zdtAuckland.toString(): 2018-05-09T08:55:14.761721+12:00[Pacific/Auckland]
zdtKolkata.toString(): 2018-05-09T02:25:14.761721+05:30[Asia/Kolkata]
zdtCasablanca.toString(): 2018-05-08T21:55:14.761721+01:00[Africa/Casablanca]
Zone vs Offset
An offset-from-UTC is simply a number of hours, minutes, and seconds. Nothing more, nothing less. Any number of time zones may share a particular offset at a particular moment.
A time zone is a history of past, present, and future changes to the offset used by the people of a particular region. For example, Daylight Saving Time (DST) is a practice where the people of a region (inexplicably) decide to change their offset twice a year.
So a time zone is always preferable to a mere offset. Having a zone allows us to add or subtract time in a meaningful way, to account for changes in offset in that region’s history.
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. Hibernate 5 & JPA 2.2 support java.time.
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), the process of API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. 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.
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode. The team advises migration to the java.time classes. Skip to java.time section below in this Answer.
The Joda-Time package has good clear support for time zones. Unlike java.util.Date, a Joda-Time DateTime does know its own assigned time zone. If you fail to specify a time zone, the JVM's current default time zone is implicitly assigned.
DateTime dateTime = DateTime.now(); // Applies JVM’s default time zone implicitly.
I recommend against relying on the default time zone implicitly. Doing so leads to confusion and errors when doing date-time work.
DateTime dateTime = DateTime.now( DateTimeZone.getDefault() ); // Explicitly using default time zone.
If needed you may assign a time zone.
DateTime dateTimeKolkata = DateTime.now( DateTimeZone.forID( "Asia/Kolkata" ) ); // Specify a time zone.
For server-side work, best practice is to do business logic and database storage in UTC.
DateTime dateTimeUtc = DateTime.now( DateTimeZone.UTC ); // Assign UTC (GMT) time zone.
You can convert from the assigned time zone to another, including the JVM's current default time zone.
DateTime dateTime = dateTimeUtc.withZone( DateTimeZone.getDefault() );
Immutable
For thread-safety, Joda-Time uses immutable objects. Instead of modifying an object, methods such as withZone create a new instance based on the original.
Parse String
To parse a String as a DateTime, you must note whether the String includes an offset from UTC and/or a time zone. Yours does not. So you must specify a time zone by which to interpret that String. If you do not specify, the JVM’s current default time zone will be used during parsing.
In your Question, you said the String represents a date-time in UTC (GMT).
DateTime dateTimeUtc = new DateTime( "2014-02-14T06:04:00:00", DateTimeZone.UTC );
After parsing, you may assign another time zone if needed. Same moment in the time-line of the Universe, but shows a different Wall-Clock time.
DateTime dateTimeDefaultZone = dateTimeUtc.withZone( DateTimeZone.getDefault() );
So notice this was a two-step process. First we parsed your String using our external knowledge of that String's intended time zone because it lacked internal representation of that time zone or offset. Secondly we adjusted the time zone to another (the JVM default zone).
If your String had included an offset of +00:00 or the customary Z, we could have collapsed those two steps into one.
DateTime dateTimeDefaultZone = new DateTime( "2014-02-14T06:04:00:00Z", DateTimeZone.getDefault() ); // Apply time zone adjustment *after* parsing.
Note that this DateTime constructor looks like the one above but is actually quite different. This one's time zone argument is applied after parsing, rather than during parsing. Here the time zone argument is used to adjust the already-parsed DateTime. That Z on the end makes a world of difference.
Source of Default Time Zone
The JVM initially gets its default time zone from the host operating system. But be aware that a programmer can override this by:
Pass an argument on command-line when launching the JVM.
Call java.util.TimeZone.setDefault.
Doing this override affects all threads of all apps running in that JVM. So you should know that the JVM’s default time zone is usually the same as host OS but not necessarily the same.
Here is a way to get the id of a TimeZone that matches your local system clock's offset,
Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
// Got local offset, now loop through available timezone id(s).
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
TimeZone tz = TimeZone.getTimeZone(id);
if (tz.getRawOffset() == milliDiff) {
// Found a match.
name = id;
break;
}
}
System.out.println(name);
private String receivedFormat = "yyyy-MM-dd'T'HH:mm:ss", expectedFormat = "dd-MM-yyyy HH:mm:ss"; //Globall variables
//Write these three lines in your Test Class and below 2 methods
String dateString = "2018-08-14T07:00:00:00";
String returnString = correctDateFormat(dateString, receivedFormat, expectedFormat);
String result = getTimeInSelectedLocale(returnString);
Log.i("Ayaz", "Date: " +result);
/**
* #param receivedDate
* #param givenFormat
* #param expectedFormat
* #return returns date time in expected format
*/
public static String correctDateFormat(String receivedDate, String givenFormat, String expectedFormat) {
if (TextUtils.isEmpty(receivedDate)) {
return "";
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(givenFormat);
Date newDate = null;
try {
newDate = simpleDateFormat.parse(receivedDate);
} catch (ParseException e) {
e.printStackTrace();
}
simpleDateFormat = new SimpleDateFormat(expectedFormat);
receivedDate = simpleDateFormat.format(newDate);
return receivedDate;
}
/**
* #param dateString
* #return passed string date in different locale, My Db is in IST so I an converting IST in different locale
*/
public String getTimeInSelectedLocale(String dateString) {
if (TextUtils.isEmpty(dateString)) {
return dateString;
}
SimpleDateFormat sdf = new SimpleDateFormat(expectedFormat);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); //We want Indian time to change in different locale, so this line is compulsory, you can replace with your country
Date date1 = null;
try {
date1 = sdf.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
//below this line -> TimeZone.getTimeZone(TimeZone.getDefault().getID(), will return current locale for example for India "Asia/Kolkata" for UAE "Asia/Dubai"
sdf.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID())); //This line chooses current local in which you want time
String localDate = sdf.format(date1);
return localDate;
}
//I am converting the IST time "2018-08-14T07:00:00:00" into UAE(Duabai) "14-08-2018 05:30:00" and other countries
I believe what you're looking for is the Joda library. It has functionality better than the Calendar or Date classes as specified in the answer here.
This function should be particularly useful.