Time information is missing when converting LocalDate to java.util.Date - java

Time information is missing when converting LocalDate to java.util.Date
My input date is in the format "2019-08-30T19:47:22+00:00" (String). I have to convert it to java.util.Data. I would like to do it using java 8.
String input = "2019-08-30T19:47:22+00:00";
Date date = null;
LocalDate dateTime = LocalDate.parse(input, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
date = Date.from(dateTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("Parsed from LoacalDate: " + date);
System.out.println("From new Date(): " + new Date());
Output
Parsed from LoacalDate: Fri Aug 30 00:00:00 CDT 2019 From new
Date(): Fri Aug 30 17:16:23 CDT 2019
In the output time information is missing. How to get time information?

tl;dr
LocalDate stores only a date, so wrong class to use.
java.util.Date // Terrible class, now legacy. Avoid. Replaced by `java.time.Instant` in JSR 310. Use only where required, to interoperate with old code not yet updated for java.time.
.from( // Convert from modern `Instant` to legacy `Date`.
OffsetDateTime // The modern class to represent a moment in the context of an offset-from-UTC (a number of hours-minutes-seconds). Not to be confused with a time zone, which is a history of changes to the offset used by the people of a particular region.
.parse( "2019-08-30T19:47:22+00:00" ) // Parse text into an `OffsetDateTime` object.
.toInstant() // Extract an `Instant`, a more basic building-block class that represent a moment in UTC (an offset of zero).
)
.toString() // Generates text representing the value of the `Date`. But this method lies! It dynamically applies your JVM’s current default time zone while generating the text.
Note that java.util.Date::toString tells a lie! That method dynamically applies the JVM’s current default time zone while generating the text to represent the value that is actually in UTC. One of many reasons to never use this Date class.
Details
You are using the wrong classes.
LocalDate
LocalDate represents a date only, no time-of-day, no time zone or offset.
By parsing your input representing a moment as simply a date, you are lopping off the time-of-day and the offset-from-UTC.
OffsetDateTime
Your input "2019-08-30T19:47:22+00:00" represents a moment: a date, a time-of-day, an offset-from-UTC of zero hours-minutes-seconds. So parse that as a OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.parse( "2019-08-30T19:47:22+00:00" ) ;
Avoid legacy date-time classes
The java.util.Date class is terrible, and should no longer be used. It was supplanted years ago by the modern java.time classes as of the adoption of JSR 310.
However, if you must interoperate with old code not yet updated to java.time, you can convert back-and-forth. Look to new to…/from… methods added to the old classes.
The equivalent of java.util.Date is java.time.Instant, both representing a moment in UTC (though with a difference in resolution, milliseconds versus nanoseconds). So extract a basic Instant object from our more flexible OffsetDateTime.
Instant instant = odt.toInstant() ;
java.util.Date d = Date.from( instant ) ;

I was able to make it work using the following code snippet
LocalDateTime dateTime = LocalDateTime.parse(input,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
date = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("Parsed from LoacalDate:" + date);
System.out.println("From new Date():" + new Date());

Related

Java, converting Calendar format to Date(YYYY-MM-DD)

Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(LeaveDate);
calendar1.add(Calendar.DAY_OF_MONTH, ProcessDate);
Date fullDate1 = calendar1.getTime();
SimpleDateFormat date1 = new SimpleDateFormat("yyyy-MM-dd");
Here the output i.e., date1 is string, how to convert it to Date
tl;dr
Reading your code, apparently you want to take the current moment as seen in the current default time zone, adjust to a particular day of month, and then convert to a moment as seen in UTC to be represented by the outmoded class java.util.Date.
java.util.Date // Legacy class. Replaced by `java.time.Instant`.
.from( // New conversion method added to old class, to move between legacy and modern classes.
ZonedDateTime // Represents a moment as seen in a particular time zone.
.now() // Implicitly applies the JVM’s current default time zone.
.withDayOfMonth( yourDesiredDayOfMonthGoesHere ) // Adjust to another moment on another date. Returns another `ZonedDateTime` object immutably, rather than altering original.
.toInstant() // Adjust from time zone to UTC. Same moment, different wall-clock time.
) // Returns an object for the same moment, but as a legacy `Date` object. Avoid using this class if at all possible.
But your title asks for something different. The title asks how to generate text in a ISO 8601 standard format (YYYY-MM-DD) for a Calendar object. Assuming your Calendar object is a GregorianCalendar object, we can cast. Then we can convert to the modern java.time.ZonedDateTime object, extract the date-only java.time.LocalDate object, and generate standard text. The java.time classes use ISO 8601 formats by default when parsing/generating text, so no need for a formatting pattern.
(GregorianCalendar) yourCalendarHere // Cast from the more general `Calendar` to the more specific `GregorianCalendar`.
.toZonedDateTime() // Convert from legacy class to modern. Same moment in the same time zone. Returns a `java.time.ZonedDateTime` object.
.toLocalDate() // Strip away the time zone and the time-of-day, leaving only the date. Returns a `java.time.LocalDate` object.
.toString() // Generate text representing the value of that date in standard ISO 8601 format, YYYY-MM-DD. Returns a `String` object.
Tip: Stop using the terribly flawed legacy date-time classes. Use only java.time.
Formatters
Here the output i.e., date1 is string, how to convert it to Date
You seem to misunderstand the classes involved.
Your date1 is a variable declared to be a SimpleDateFormat object. That class is a formatter. As a formatter, its job is to generate text, not hold text nor hold a date. So your variable is misnamed, as it does not hold a date.
Avoid legacy classes
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310. Never use Date, Calendar, SimpleDateFormat, and such.
java.time
Replace this:
Calendar calendar1 = Calendar.getInstance();
… with this:
ZonedDateTime zdt = ZonedDateTime.now() ; // Implicitly uses the JVM’s current default time zone.
I assume that in this code:
calendar1.setTime(LeaveDate);
… the LeaveDate (should have been named with initial lowercase, leaveDate) represents a java.util.Date object. And you are trying to get a calendar object set to the moment represented by that Date object.
In java.time, we use immutable objects. So, no use of set methods. In java.time, if handed a java.util.Date object, immediately convert to an Instant. Both classes represent a moment as seen in UTC, with an offset of zero hours-minutes-seconds. To convert, use the new conversion methods added to the old classes.
Instant instant = leaveDate.toInstant() ;
Adjust that moment into a time zone.
ZoneId z = ZoneId.systemDefault() ; // The JVM’s current default time zone.
ZonedDateTime zdt = instant.atZone( z ) ;
Both instant & zdt represent the same moment, the very same point on the timeline. But their date and time-of-day are adjusted for the wall-clock time used by the people of two different regions. If someone in Iceland, where they use UTC as their time zone, called someone in Tokyo, and both people looked up to see the calendar and clock on their respective walls, they would see a different time and possibly a different date.
In your line:
calendar1.add(Calendar.DAY_OF_MONTH, ProcessDate);
… I am guessing that you want to set the day-of-month while keeping the same month, year, and time-of-day. For example, let's use the 23rd. Notice that we generate a new ZonedDateTime rather than alter ("mutate") the original. Adjustments are made automatically if the result would be impossible, such as the 30th of February.
ZonedDateTime zdtForSpecificDayOfMonth = zdt.withDayOfMonth( 23 ) ; // Change day-of-month to the 23rd.
Regarding your line:
Date fullDate1 = calendar1.getTime();
… as I said above, you should avoid using Date in modern Java. But if you must do so to interoperate with old code not yet updated to java.time, extract an Instant from the ZonedDateTime object, and convert to a java.util.Date.
Instant instant = zdtForSpecificDayOfMonth.toInstant() ; // Adjust from a time zone to an offset of zero hours-minutes-seconds.
java.util.Date d = Date.from( instant ) ;
Parsing dates in Java with DateFormat or descendants
Tested with Java's REPL jshell
jshell> import java.text.SimpleDateFormat;
jshell> var df = new SimpleDateFormat("yyyy-MM-dd");
df ==> java.text.SimpleDateFormat#f67a0200
jshell> Date dt = df.parse("2022-02-15");
dt ==> Tue Feb 15 00:00:00 CET 2022
Read the official JavaDoc for class SimpleDateFormat to figure out how to use it to parse a String to Date:
import java.text.SimpleDateFormat;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date dt = df.parse("2022-02-15");
System.out.println(dt); // prints Tue Feb 15 00:00:00 CET 2022
Explained:
The "yyyy-MM-dd" as argument to the constructor is a date-format literal (representing ISO-date format).
The parse method parses a String with this format and returns the Date object if valid format, or throws a ParseException.
Or search Stackoverflow for [java] String to Date to find similar questions.
Formatting dates in Java with DateFormat or descendants
The other way round you can also format a Date object to have a well-formatted String representation. Use the format method of your DateFormat instance:
import java.text.SimpleDateFormat;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date dt = df.parse("2022-02-15");
String formatted = df.format(dt);
System.out.println(formatted);
For example to format your Calendar instance use:
Calendar calendar1 = Calendar.getInstance();
// whatever modifies the calendar left out here
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formatted = df.format(dt);
System.out.println(calendar1.getTime());

transform java.sql.Date to LocalDateTime

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.

Unable to convert the IST to UTC [duplicate]

I have parsed a java.util.Date from a String but it is setting the local time zone as the time zone of the date object.
The time zone is not specified in the String from which Date is parsed. I want to set a specific time zone of the date object.
How can I do that?
Use DateFormat. For example,
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
Be aware that java.util.Date objects do not contain any timezone information by themselves - you cannot set the timezone on a Date object. The only thing that a Date object contains is a number of milliseconds since the "epoch" - 1 January 1970, 00:00:00 UTC.
As ZZ Coder shows, you set the timezone on the DateFormat object, to tell it in which timezone you want to display the date and time.
tl;dr
…parsed … from a String … time zone is not specified … I want to set a specific time zone
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
No Time Zone in j.u.Date
As the other correct answers stated, a java.util.Date has no time zone†. It represents UTC/GMT (no time zone offset). Very confusing because its toString method applies the JVM's default time zone when generating a String representation.
Avoid j.u.Date
For this and many other reasons, you should avoid using the built-in java.util.Date & .Calendar & java.text.SimpleDateFormat. They are notoriously troublesome.
Instead use the java.time package bundled with Java 8.
java.time
The java.time classes can represent a moment on the timeline in three ways:
UTC (Instant)
With an offset (OffsetDateTime with ZoneOffset)
With a time zone (ZonedDateTime with ZoneId)
Instant
In java.time, the basic building block is Instant, a moment on the time line in UTC. Use Instant objects for much of your business logic.
Instant instant = Instant.now();
OffsetDateTime
Apply an offset-from-UTC to adjust into some locality’s wall-clock time.
Apply a ZoneOffset to get an OffsetDateTime.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Better is to apply a time zone, an offset plus the rules for handling anomalies such as Daylight Saving Time (DST).
Apply a ZoneId to an Instant to get a ZonedDateTime. Always specify a proper time zone name. Never use 3-4 abbreviations such as EST or IST that are neither unique nor standardized.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
If the input string lacked any indicator of offset or zone, parse as a LocalDateTime.
If you are certain of the intended time zone, assign a ZoneId to produce a ZonedDateTime. See code example above in tl;dr section at top.
Formatted Strings
Call the toString method on any of these three classes to generate a String representing the date-time value in standard ISO 8601 format. The ZonedDateTime class extends standard format by appending the name of the time zone in brackets.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
For other formats use the DateTimeFormatter class. Generally best to let that class generate localized formats using the user’s expected human language and cultural norms. Or you can specify a particular format.
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), a process known as 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….
Joda-Time
While Joda-Time is still actively maintained, its makers have told us to migrate to java.time as soon as is convenient. I leave this section intact as a reference, but I suggest using the java.time section above instead.
In Joda-Time, a date-time object (DateTime) truly does know its assigned time zone. That means an offset from UTC and the rules and history of that time zone’s Daylight Saving Time (DST) and other such anomalies.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Call the toString method to generate a String in ISO 8601 format.
String output = dateTimeIndia.toString();
Joda-Time also offers rich capabilities for generating all kinds of other String formats.
If required, you can convert from Joda-Time DateTime to a java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Search StackOverflow for "joda date" to find many more examples, some quite detailed.
†Actually there is a time zone embedded in a java.util.Date, used for some internal functions (see comments on this Answer). But this internal time zone is not exposed as a property, and cannot be set. This internal time zone is not the one used by the toString method in generating a string representation of the date-time value; instead the JVM’s current default time zone is applied on-the-fly. So, as shorthand, we often say “j.u.Date has no time zone”. Confusing? Yes. Yet another reason to avoid these tired old classes.
You could also set the timezone at the JVM level
Date date1 = new Date();
System.out.println(date1);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"
Date date2 = new Date();
System.out.println(date2);
output:
Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
If you must work with only standard JDK classes you can use this:
/**
* Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
* <code>toTimeZone</code>. Since java.util.Date has does not really store time zome
* information, this actually converts the date to the date that it would be in the
* other time zone.
* #param date
* #param fromTimeZone
* #param toTimeZone
* #return
*/
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);
return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}
/**
* Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
* additional offset due to the time zone being in daylight savings time as of
* the given <code>date</code>.
* #param date
* #param timeZone
* #return
*/
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
long timeZoneDSTOffset = 0;
if(timeZone.inDaylightTime(date))
{
timeZoneDSTOffset = timeZone.getDSTSavings();
}
return timeZone.getRawOffset() + timeZoneDSTOffset;
}
Credit goes to this post.
java.util.Calendar is the usual way to handle time zones using just JDK classes. Apache Commons has some further alternatives/utilities that may be helpful. Edit Spong's note reminded me that I've heard really good things about Joda-Time (though I haven't used it myself).
Convert the Date to String and do it with SimpleDateFormat.
SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
String dateStr = readFormat.format(date);
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = writeFormat.parse(dateStr);
This code was helpful in an app I'm working on:
Instant date = null;
Date sdf = null;
String formatTemplate = "EEE MMM dd yyyy HH:mm:ss";
try {
SimpleDateFormat isoFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("US/Pacific")));
sdf = isoFormat.parse(timeAtWhichToMakeAvailable);
date = sdf.toInstant();
} catch (Exception e) {
System.out.println("did not parse: " + timeAtWhichToMakeAvailable);
}
LOGGER.info("timeAtWhichToMakeAvailable: " + timeAtWhichToMakeAvailable);
LOGGER.info("sdf: " + sdf);
LOGGER.info("parsed to: " + date);
Here you be able to get date like "2020-03-11T20:16:17" and return "11/Mar/2020 - 20:16"
private String transformLocalDateTimeBrazillianUTC(String dateJson) throws ParseException {
String localDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss";
SimpleDateFormat formatInput = new SimpleDateFormat(localDateTimeFormat);
//Here is will set the time zone
formatInput.setTimeZone(TimeZone.getTimeZone("UTC-03"));
String brazilianFormat = "dd/MMM/yyyy - HH:mm";
SimpleDateFormat formatOutput = new SimpleDateFormat(brazilianFormat);
Date date = formatInput.parse(dateJson);
return formatOutput.format(date);
}
If anyone ever needs this, if you need to convert an XMLGregorianCalendar timezone to your current timezone from UTC, then all you need to do is set the timezone to 0, then call toGregorianCalendar() - it will stay the same timezone, but the Date knows how to convert it to yours, so you can get the data from there.
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(
((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());
Result:
2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00
This answer is probably the shortest and it uses only the Date class:
long current = new Date().getTime() + 3_600_000; //e.g. your JVM time zone +1 hour (3600000 milliseconds)
System.out.printf("%1$td.%1$tm.%1$tY %1$tH:%1$tM\n", current);//european time format
But, if you can, use more modern ways to doing the same.
package org.example;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class time {
public static void main(String[] args) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Jakarta"));
Date date=new Date();
sdf.format(date);
System.out.println(sdf.format(date));
}
}

java android display current time in multiple time zones [duplicate]

I have parsed a java.util.Date from a String but it is setting the local time zone as the time zone of the date object.
The time zone is not specified in the String from which Date is parsed. I want to set a specific time zone of the date object.
How can I do that?
Use DateFormat. For example,
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
Be aware that java.util.Date objects do not contain any timezone information by themselves - you cannot set the timezone on a Date object. The only thing that a Date object contains is a number of milliseconds since the "epoch" - 1 January 1970, 00:00:00 UTC.
As ZZ Coder shows, you set the timezone on the DateFormat object, to tell it in which timezone you want to display the date and time.
tl;dr
…parsed … from a String … time zone is not specified … I want to set a specific time zone
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
No Time Zone in j.u.Date
As the other correct answers stated, a java.util.Date has no time zone†. It represents UTC/GMT (no time zone offset). Very confusing because its toString method applies the JVM's default time zone when generating a String representation.
Avoid j.u.Date
For this and many other reasons, you should avoid using the built-in java.util.Date & .Calendar & java.text.SimpleDateFormat. They are notoriously troublesome.
Instead use the java.time package bundled with Java 8.
java.time
The java.time classes can represent a moment on the timeline in three ways:
UTC (Instant)
With an offset (OffsetDateTime with ZoneOffset)
With a time zone (ZonedDateTime with ZoneId)
Instant
In java.time, the basic building block is Instant, a moment on the time line in UTC. Use Instant objects for much of your business logic.
Instant instant = Instant.now();
OffsetDateTime
Apply an offset-from-UTC to adjust into some locality’s wall-clock time.
Apply a ZoneOffset to get an OffsetDateTime.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Better is to apply a time zone, an offset plus the rules for handling anomalies such as Daylight Saving Time (DST).
Apply a ZoneId to an Instant to get a ZonedDateTime. Always specify a proper time zone name. Never use 3-4 abbreviations such as EST or IST that are neither unique nor standardized.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
If the input string lacked any indicator of offset or zone, parse as a LocalDateTime.
If you are certain of the intended time zone, assign a ZoneId to produce a ZonedDateTime. See code example above in tl;dr section at top.
Formatted Strings
Call the toString method on any of these three classes to generate a String representing the date-time value in standard ISO 8601 format. The ZonedDateTime class extends standard format by appending the name of the time zone in brackets.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
For other formats use the DateTimeFormatter class. Generally best to let that class generate localized formats using the user’s expected human language and cultural norms. Or you can specify a particular format.
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), a process known as 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….
Joda-Time
While Joda-Time is still actively maintained, its makers have told us to migrate to java.time as soon as is convenient. I leave this section intact as a reference, but I suggest using the java.time section above instead.
In Joda-Time, a date-time object (DateTime) truly does know its assigned time zone. That means an offset from UTC and the rules and history of that time zone’s Daylight Saving Time (DST) and other such anomalies.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Call the toString method to generate a String in ISO 8601 format.
String output = dateTimeIndia.toString();
Joda-Time also offers rich capabilities for generating all kinds of other String formats.
If required, you can convert from Joda-Time DateTime to a java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Search StackOverflow for "joda date" to find many more examples, some quite detailed.
†Actually there is a time zone embedded in a java.util.Date, used for some internal functions (see comments on this Answer). But this internal time zone is not exposed as a property, and cannot be set. This internal time zone is not the one used by the toString method in generating a string representation of the date-time value; instead the JVM’s current default time zone is applied on-the-fly. So, as shorthand, we often say “j.u.Date has no time zone”. Confusing? Yes. Yet another reason to avoid these tired old classes.
You could also set the timezone at the JVM level
Date date1 = new Date();
System.out.println(date1);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"
Date date2 = new Date();
System.out.println(date2);
output:
Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
If you must work with only standard JDK classes you can use this:
/**
* Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
* <code>toTimeZone</code>. Since java.util.Date has does not really store time zome
* information, this actually converts the date to the date that it would be in the
* other time zone.
* #param date
* #param fromTimeZone
* #param toTimeZone
* #return
*/
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);
return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}
/**
* Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
* additional offset due to the time zone being in daylight savings time as of
* the given <code>date</code>.
* #param date
* #param timeZone
* #return
*/
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
long timeZoneDSTOffset = 0;
if(timeZone.inDaylightTime(date))
{
timeZoneDSTOffset = timeZone.getDSTSavings();
}
return timeZone.getRawOffset() + timeZoneDSTOffset;
}
Credit goes to this post.
java.util.Calendar is the usual way to handle time zones using just JDK classes. Apache Commons has some further alternatives/utilities that may be helpful. Edit Spong's note reminded me that I've heard really good things about Joda-Time (though I haven't used it myself).
Convert the Date to String and do it with SimpleDateFormat.
SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
String dateStr = readFormat.format(date);
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = writeFormat.parse(dateStr);
This code was helpful in an app I'm working on:
Instant date = null;
Date sdf = null;
String formatTemplate = "EEE MMM dd yyyy HH:mm:ss";
try {
SimpleDateFormat isoFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("US/Pacific")));
sdf = isoFormat.parse(timeAtWhichToMakeAvailable);
date = sdf.toInstant();
} catch (Exception e) {
System.out.println("did not parse: " + timeAtWhichToMakeAvailable);
}
LOGGER.info("timeAtWhichToMakeAvailable: " + timeAtWhichToMakeAvailable);
LOGGER.info("sdf: " + sdf);
LOGGER.info("parsed to: " + date);
Here you be able to get date like "2020-03-11T20:16:17" and return "11/Mar/2020 - 20:16"
private String transformLocalDateTimeBrazillianUTC(String dateJson) throws ParseException {
String localDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss";
SimpleDateFormat formatInput = new SimpleDateFormat(localDateTimeFormat);
//Here is will set the time zone
formatInput.setTimeZone(TimeZone.getTimeZone("UTC-03"));
String brazilianFormat = "dd/MMM/yyyy - HH:mm";
SimpleDateFormat formatOutput = new SimpleDateFormat(brazilianFormat);
Date date = formatInput.parse(dateJson);
return formatOutput.format(date);
}
If anyone ever needs this, if you need to convert an XMLGregorianCalendar timezone to your current timezone from UTC, then all you need to do is set the timezone to 0, then call toGregorianCalendar() - it will stay the same timezone, but the Date knows how to convert it to yours, so you can get the data from there.
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(
((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());
Result:
2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00
This answer is probably the shortest and it uses only the Date class:
long current = new Date().getTime() + 3_600_000; //e.g. your JVM time zone +1 hour (3600000 milliseconds)
System.out.printf("%1$td.%1$tm.%1$tY %1$tH:%1$tM\n", current);//european time format
But, if you can, use more modern ways to doing the same.
package org.example;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class time {
public static void main(String[] args) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Jakarta"));
Date date=new Date();
sdf.format(date);
System.out.println(sdf.format(date));
}
}

Convert String to Util Date using simpleDateFormat not working

I'm having a String having date in it, I need hh:mm:ss to be added to the date, but when i use dateFormat it gives me ParseException. Here is the code:
DateFormat sdff = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String startDate = "2013-09-25";
Date frmDate;
frmDate = sdff.parse(startDate);
System.out.println("from date = " + frmDate);
I get parse exception for the abv code. But if i remove the hh:mm:ss from the Date format it works fine and the output will be from date = Wed Sep 25 00:00:00 IST 2013.
But I need output like from date = 2013-09-25 00:00:00
Please help me.
Thanks in advance.
You'll need 2 SimpleDateFormat objects for that. One to parse your current date string and the other to format that parsed date to your desired format.
// This is to parse your current date string
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String startDate = "2013-09-25";
Date frmDate = sdf.parse(startDate); // Handle the ParseException here
// This is to format the your current date to the desired format
DateFormat sdff = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String frmDateStr = sdff.format(frmDate);
Edit:-
Date doesn't have a format as such. You can only get a String representation of it using the SDF. Here an excerpt from the docs
A thin wrapper around a millisecond value that allows JDBC to identify
this as an SQL DATE value. A milliseconds value represents the number
of milliseconds that have passed since January 1, 1970 00:00:00.000
GMT.
And regarding your problem to insert it in the DB, java Date can be as such persisted in the DB date format. You don't need to do any formatting. Only while fetching the date back from DB, you can use the to_char() method to format it.
parse() is used to convert String to Date.It requires the formats to be matched otherwise you will get exception.
format() is used convert the date into date/time string.
Accroding to your requirement you need to use above two methods.
DateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String startDate = "2013-09-25";
Date parsedDate = parser.parse(startDate);
String formattedDate = dateFormatter.format(parsedDate);//this will give your expected output
tl;dr
LocalDate.parse( "2013-09-25" ) // Parse the string as a date-only object lacking time-of-day and lacking time zone.
.atStartOfDay( // Let java.time determine the first moment of the day. Not always 00:00:00 because of anomalies such as Daylight Saving Time (DST).
ZoneId.of( "America/Montreal" ) // Specify a time zone using legitimate `continent/region` name rather than 3-4 letter pseudo-zones.
) // Returns a `ZonedDateTime` object.
.toString() // Generate a string in standard ISO 8601 format, wisely extended from the standard by appending the name of the time zone in square brackets.
2013-09-25T00:00-04:00[America/Montreal]
To generate your string, pass a DateTimeFormatter.
LocalDate.parse( "2013-09-25" ) // Parse the string as a date-only object lacking time-of-day and lacking time zone.
.atStartOfDay( // Let java.time determine the first moment of the day. Not always 00:00:00 because of anomalies such as Daylight Saving Time (DST).
ZoneId.of( "America/Montreal" ) // Specify a time zone using legitimate `continent/region` name rather than 3-4 letter pseudo-zones.
) // Returns a `ZonedDateTime` object.
.format( // Generate a string representing the value of this `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // Formatter that omits zone/offset.
).replace( "T" , " " ) // Replace the standard’s required 'T' in the middle with your desired SPACE character.
2013-09-25 00:00:00
Details
Your formatting pattern must match your input, as pointed out by others. One formatter is needed for parsing strings, another for generating strings.
Also, you are using outmoded classes.
java.time
The modern approach uses the java.time classes that supplanted the troublesome old legacy date-time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
You can parse a string to produce a LocalDate. The standard ISO 8601 formats are used in java.time by default. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( "2013-09-25" ) ;
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
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( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 2013 , 9 , 25 ) ; // Years use sane direct numbering (2013 means year 2013). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 2013 , Month.SEPTEMBER , 25 ) ;
Formats
If you want to get the first moment of the day for that date, apply a time zone. As mentioned above, a date and time-of-day require the context of a time zone or offset-from-UTC to represent a specific moment on the timeline.
Do not assume the day starts at 00:00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at another time such as 01:00:00. Let java.time determine the first moment of the day.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ld.atZone( z ) ;
If you want output in the format shown in your Question, you can define your own format. I caution you against omitting the time zone or offset info from the resulting string unless you are absolutely certain the user can discern its meaning from the greater context.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = zdt.format( f ) ;
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.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or 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.
It is because your string is yyyy-MM-dd, but the date format u defined is yyyy-MM-dd hh:mm:ss.
If you change your string startDate to yyyy-MM-dd hh:mm:ss it should work
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.parse(sdf.format(new Date()));
This will return a Date type
The issue is '2013-09-25' date cannot be parsed to 'yyyy-MM-dd hh:mm:ss' date format. First you need to parse following date into its matching pattern which is 'yyyy-MM-dd'.
Once it is parsed to its correct pattern you can provide the date pattern you prefer which is 'yyyy-MM-dd hh:mm:ss'.
Now you can format the Date and it will output the date as you preferred.
SimpleDateFormat can be used to achieve this outcome.
Try this code.
String startDate = "2013-09-25";
DateFormat existingPattern = new SimpleDateFormat("yyyy-MM-dd");
DateFormat newPattern = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = existingPattern.parse(startDate);
String formattedDate = newPattern.format(date);
System.out.println(formattedDate); //outputs: 2013-09-25 00:00:00

Categories

Resources