Issue with String to Date conversion after Timezone parsing - java

I am trying to convert a date to a specified timezone and return the converted date. But the code always returns the unconverted date. Can any help with the same.
public static Date testUserSpecifiedConv(String toTimezone, Date inputDate) {
System.out.println(inputDate);
Date convertedDate = null;
String inputDateStr ;
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone(toTimezone));
inputDateStr = df.format(inputDate);
System.out.println("Formatted Date In String Format: " + inputDateStr);
//Now trying to convert it back to date
try {
convertedDate = df.parse(inputDateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return convertedDate;
}
public static void main(String args[]) {
System.out.println("Formatted Date In Date Format: "+testUserSpecifiedConv("EST", new Date()));
}
Output is
Fri Mar 31 15:58:50 IST 2017
Formatted Date In String Format: 03/31/2017 05:28:50
Formatted Date In Date Format: Fri Mar 31 15:58:50 IST 2017
The formatted date in string and date format in output is different.

The class java.util.Date does represent a specific point in time and is timezone independent per se.
Nevertheless you can apply the timezone to the SimpleDateFormat to format your date accordingly to be presented in a certain timezone (e.g. if you want a formatted string to be shown somewhere).
Still, if you now parse back the formatted date, the date object itself will again not contain any information about the timezone.
If you want to work with timezones on an object level you might have a look into ZonedDateTime.
Update:
Assuming you want to convert a given String to an object containing the information about the date in a certain timezone you could do it like that:
ZonedDateTime dateTime = ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Paris]");

Date instance does not retain any formatting information. For further details look at the Stackoverflow question. You will get your answer with a better insight to the Date object.

java.time
The Answer by JDC has the right idea.
I will show how to use the modern java.time classes that supplant the troublesome old legacy date-time classe (Date, Calendar, etc.) that should be avoided.
Firstly, your two arguments.
Pass ZoneId objects around rather than mere strings. Doing so provides type-safety, ensures valid values, and makes your code more self-documenting.
Date is outmoded, convert to Instant and pass that instead.
For 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( "America/Montreal" );
For the Date, convert to its equivalent in 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). Like Date, an Instant is always in UTC.
To convert between legacy classes and java.time classes, look to new methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant();
Assign a ZoneId to generate a ZonedDateTime object.
ZonedDateTime zdt = instant.atZone( z );
Generate a string representing that value using a DateTimeFormatter. Do not conflate a date-time object with a string representation of its value.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm:ss" , Locale.US );
String output = zdt.format( f );

Related

how to convert date in yyyy-MM-dd format of date type? [duplicate]

This question already has answers here:
Change date format in a Java string
(22 answers)
want current date and time in "dd/MM/yyyy HH:mm:ss.SS" format
(11 answers)
How to convert date in to yyyy-MM-dd Format?
(6 answers)
display Java.util.Date in a specific format
(11 answers)
Closed 3 years ago.
I know that this question that I am asking has answer all over the net but I want the yyyy-MM-dd format in Date type as SimpleDateFormat.format("yyyy-MM-dd") returns the string value and also I have tried SimpleDateFormat.parse("yyyy-MM-dd") but it does not provide the value in required format. Could anyone help how to get "yyyy-MM-dd" format in Date type variable. Example what I am trying to do is shown below-
Date date = new Date(); // this will give the outpur something like this Thu 28 Nov....
But I want the output in this format 2019-11-28 where date variable should not change its type.
tl;dr
Capture the current date, using java.time.LocalDate.
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.now( // Capture the current date. Time zone required, as the date is not the same around the globe.
ZoneId.of( "Pacific/Auckland" )
) // Returns a `LocalDate` object.
.toString() // Generates a `String` object whose text is in standard ISO 8601 format: YYYY-MM-DD
2020-01-23
Perhaps you are being handed a java.util.Date object by old code not yet updated to java.time classes. Convert from a given java.util.Date object (legacy) to Instant & ZonedDateTime (modern).
myJavaUtilDate // `java.util.Date` is one of the terrible date-time classes, now legacy.
.toInstant() // Convert to the modern `java.time.Instant` class that replaces `Date`.
.atZone( // Adjust from UTC to the time zone through which you want to perceive the date.
ZoneId.of( "Asia/Tokyo" ) // Specify a proper time zone in `Continent/Region` format, never 2-4 letter pseudo-zone such as PDT, CST, IST, and such.
) // Returns a `ZonedDateTime` object.
.format( // Generate text representing the value within our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE // Specify a formatter. Here, the standard ISO 8601 formatter for date-only value: YYYY-MM-DD.
) // Returns a `String`.
2020-01-23
java.time
You are using terrible date-time classes that were supplanted years ago by the java.time classes defined in JSR 310.
LocalDate
If you just want the current date, use LocalDate.now.
LocaleDate.now( ZoneId.of( "Europe/Berlin" ) ).toString() // Yields something like '2020-01-23'.
Instant
Convert java.util.Date to its replacement, java.time.Instant. Both represent a moment in UTC, though the modern class has a fiber resolution of nanoseconds versus milliseconds.
To convert, use new to/from methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
ZonedDateTime
For any given moment, the date varies around the globe by time zone. A few minutes after midnight in Paris France is a new day, while still “yesterday” in Montréal Québec.
So determining a date requires a time zone.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Text
Could anyone help how to get "yyyy-MM-dd" format in Date type variable.
Text has a “format”, but date-time objects do not. Date-time objects can be instantiated by parsing text. Date-time objects can generate text to represent t the value held internally. But the date-time object and the String object are separate and distinct.
Generate text for the date only, without the time of day and without the time zone appearing.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE ) ;
Convert it to java.sql.Date :
Date obj = new Date();
java.sql.Date sqlDate = new java.sql.Date(obj.getTime());
System.out.println(sqlDate);
Try this one:
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
String strDate= formatter.format(date);
System.out.println(strDate);
or check this site: https://www.javatpoint.com/java-simpledateformat
I don't think that you can change the format of a Date object itself, therefore you should use DateFormatters, like mentioned above the SimpleDateFormat.
Also, you maybe should consider using LocalDate/LocalDateTime or Instant instead of Date.

What is the easiest way to get a formatted string from a calendar object which respects timezone?

When I search online about "how to convert a Calendar to a String", all the results I find suggest to first convert to a Date and then convert the Date to a String.
The problem is that a Date is only a representation of the number of milliseconds since the epoch - it does not respect timezone. Calendar is more advanced in this way.
Of course, I could call the individual Calendar.get methods to create my own formatted string, but surely there must be an easier way?
To illustrate, I wrote this code:
long currentTime = Calendar.getInstance().getTimeInMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
calendar.setTimeInMillis(currentTime);
System.out.println(calendar.getTime().toString());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
While running this code from a machine based in London (UTC+0) at 8:02pm, I got the following results:
Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21
The last line shows the real hour according to the calendar's timezone (Madrid which is UTC+1). It is 9:02pm in Madrid, but obviously both the native Date.toString as well as the DateFormat.format methods ignore the timezone because the timezone information is erased when calling Calendar.getTime (similarly Calendar.getTimeInMillis).
Given this, what is the best way to get a formatted string from a Calendar which respects timezone?
Set the timezone on the SimpleDateFormat object and then use z ..
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
System.out.println(sdf.format(calendar.getTime());
See here for details on how to handle timezones in Java.
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
Calendar cal = Calendar.getInstance();
System.out.println(simpleDateFormat.format(cal.getTime()));
java.time
While the other Answers appear to be correct, a better approach is to avoid using java.util.Date/.Calendar entirely.
Those old date-time classes have been superseded by the java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
Instant
An Instant represents a moment on the timeline in UTC.
Instant instant = Instant.now ( ); // Current moment in UTC.
For a given Calendar object, convert to an Instant using the method toInstant added in Java 8.
Instant instant = myCalendar.toInstant();
ZonedDateTime
You can assign a time zone (ZoneId) to an Instant to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of ( "Europe/Madrid" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant, zoneId );
String Representation of Date-Time Value
Dump to console.
System.out.println ( "instant: " + instant + " adjusted into zone: " + zoneId + " is zdt: " + zdt );
The java.time classes use ISO 8601 standard formatting by default when parsing/generating String representations of date-time values. By default the ISO 8601 style is extended by appending the name of the time zone in addition to the usual offset-from-UTC.
instant: 2015-11-18T22:23:46.764Z adjusted into zone: Europe/Madrid is zdt: 2015-11-18T23:23:46.764+01:00[Europe/Madrid]
If you want the ISO 8601 style but without the T, either call .replace( "T" , "" ) on the resulting String object or define your own formatter.
The java.time.format package can do the work of determining a localized format appropriate to a particular Locale.
Locale locale = Locale.forLanguageTag ( "es-ES" );
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
String output = zdt.format ( formatter.withLocale ( locale ) );
miércoles 18 de noviembre de 2015 23H38' CET
You can use String.format() to avoid timezone problems
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
This example gives a result in the format: "yyyy-MM-dd HH:mm:ss"
Calendar c = Calendar.getInstance();
String s = String.format("%1$tY-%1$tm-%1$td:%1$tM:%1$tS", c);
System.out.println(s);
Output:
2015-11-20:44:55

Creating timestamps and dates in java

There are many java classes that handle time (date, calander..etc) and there are even more references and tutorials online which makes it all very confusing and I don't know which class to use when.
Can anyone give me straightforward statements to do the following:
Create an instance of a timestamp to keep track of transactions on a database
Create an object that holds today's date in DD/MM/YY format (or anything similar)
Create an object that holds ANY given date in DD/MM/YY format (or anything similar)
Much appreciated!
Ans1
You can get current date using.
Date date = new Date();
In SQL you can mark the date field to update to current time automatically.
Ans2
SimpleDateFormat allows a variety of date formats. An example usage is:
Date d = new Date(secondsSunceEpoch);
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
String time = df.format(d);
Ans3
Use parse method from SimpleDateFormat for any string would work.
try {
DateFormat todaysDateFormat = new SimpleDateFormat("dd/mm/yy");
Date date = new Date();
//2. datestring hold your today's object in DD/MM/YY format
String datestring = todaysDateFormat.format(date);
System.out.println("datestring "+datestring);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/mm/yy");
java.util.Date parsedDate;
parsedDate = dateFormat.parse(datestring);
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
//1. Create an instance of a timestamp to keep track of transactions on a database
System.out.println(timestamp); // Use this time stamp as today's date foramt
// 3.Create an object that holds ANY given date in DD/MM/YY format
SimpleDateFormat dateFormat3 = new SimpleDateFormat("dd/mm/yy");
java.util.Date parsedDate3;
parsedDate3 = dateFormat.parse("30/12/14"); // any given date
String anyDatestring = todaysDateFormat.format(date);
// it will hold any date string
}catch (ParseException e) {
e.printStackTrace();
}
The other Answers are correct but outdated. They use troublesome old legacy classes. Instead use java.time classes.
1
Create an instance of a timestamp to keep track of transactions on a database
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
In Java 8 the current moment is captured with milliseconds resolution. In Java 9, up to nanosecond resolution. In both versions of Java, the Instant class is capable of holding a nanosecond value.
Instant now = Instant.now();
In JDBC 4.2 and later, exchange with your database via the PreparedStatement::setObject and ResultSet::getObject. If your driver cannot do so, convert to a java.sql.Timestamp.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
Going the other direction.
Instant instant = ts.toInstant();
2
Create an object that holds today's date in DD/MM/YY format (or anything similar)
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
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.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
To generate a String you can specify a formatting pattern, or just let DateTimeFormatter localize. A Locale determines (a) the human language used for translation, and (b) the cultural norms for deciding issues like capitalization, abbreviation, and punctuation.
DateTimeFormatter f = DateTimeFormatter.ofLocalizeDate( FormatStyle.SHORT ).withLocale( Locale.UK );
String output = today.format( f );
3
Create an object that holds ANY given date in DD/MM/YY format (or anything similar)
Do not conflate a date-time object with a String representation of that date-time value. The object can parse or generate such strings but is separate and distinct from the string.
So we already saw the solution above: a LocalDate object holds the date-only value. When needed for presentation to the user, generate a String to represent the value.
By the way, calling toString gets you a String in standard ISO 8601 format, YYYY-MM-DD.
String output = localDate.toString();
The java.time classes follow the immutable object pattern. So you do not modify an existing object to alter part of its value. Instead you create a new object with parts of its value based on the original object.
LocalDate tomorrow = today.plusDays( 1 );

Java converting string, having millisecond to date object

I have 2 Strings
2012-06-25 15:02:22.948
+0530
I need a new string which adds the 5:30 to the time in the first string.
I thought I can do this by converting both strings to date objects and then adding. But i dont know how to do it, as when i use
yyyy MM dd hh:mm:ss as the date format for the first string, I get an error.
Thanks!
The format of the string 2012-06-25 15:02:22.948 is not yyyy MM dd hh:mm:ss, so it's not surprising that you get "an error" (what error is it? the more specific you are, the better people can help you!).
Try yyyy-MM-dd HH:mm:ss.SSS. See the API documentation of SimpleDateFormat to understand the exact syntax of the format string.
Note: Upper and lower case is important in the format string. hh means 12-hour clock, HH means 24-hour clock. If you use hh, parsing 15 for the hours won't work. You also didn't include the milliseconds SSS in the format string.
You can merge both you string String1+string2 and can use format yyyy-MM-dd HH:mm:ss.SSSZ to parse the date. You can see more documentation here
You're getting an exception because the your date format String is wrong. You're giving a date string on the form
"yyyy-MM-dd hh:mm:ss.S"
See SimpleDateFormat javadoc
Try this:
DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
Date date = format.parse("2012-06-25 15:02:22.948");
Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(date.getTime());
int time = Integer.parseInt("0530");
int hour = time / 100;
int minute = time % 100;
calendar.add(Calendar.HOUR_OF_DAY, hour);
calendar.add(Calendar.MINUTE, minute);
String newDateInString = format.format(calendar.getTime());
The other answers are correct but outdated.
java.time
The old date-time classes (java.util.Date/.Calendar etc.) bundled with the earliest versions of Java are now legacy.
Those old classes have been supplanted by the java.time package. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDateTime
The LocalDateTime class represent a date-time without time zone. Use those for the first piece.
Your format is close to standard ISO 8601 format, just replace the SPACE with a T.
String input = "2012-06-25 15:02:22.948";
String inputStandardized = input.replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( inputStandardized );
Offset from UTC
The other piece is the offset-from-UTC. We use the ZoneOffset class for this.
ZoneOffset offset = ZoneOffset.of( "+0530" );
Without an offset or time zone the LocalDateTime is not an actual moment on the timeline but rather a rough idea about a possible moment. Now we add your offset-from-UTC to mark an actual moment, represented by the OffsetDateTime class.
OffsetDateTime odt = OffsetDateTime.of( ldt , offset );
Zoned
A time zone is an offset plus rules for handling anomalies such as Daylight Saving Time (DST). So better to use a time zone than a mere offset.
For example, if the context of this data is known to be time in India, use a time zone such as Asia/Kolkata to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId );

How to convert java date without Z to a date with Z

I have the following date value 1995-12-31T23:59:59
but in order to parse this for a solr query I need it in the below format
1995-12-31T23:59:59Z
How can I parse this to get the added "Z" on the end in java 1.6 ?
The type must be java.util.date after the conversion - fyi
When I toString the date now and attempt to parse it with the SimpleDateFormat object it looks like this
"Mon Jan 01 00:00:00 CST 2001" - what is this format to convert it?
Use SimpleDateFormat:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date d = df.parse("1995-12-31T23:59:59Z");
System.out.println(d);
Put the 'Z' in single quotes to escape
"Z" is the time zone abbreviation for Zulu time zone i.e. UTC. If solr API accepts the date object, then you can just parse the date in the following way by setting preferred timezone:
SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateParser.setTimeZone(TimeZone.getTimeZone("Z"));
Date date = df.parse("1995-12-31T23:59:59");
If you need to convert it back to string then use the method provided by nsfyn55:
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
System.out.println(dateFormatter.format());
Avoid Old Date-Time Classes
You are using the old java.util.Date/.Calendar and SimpleDateFormat classes. Avoid them.
The Date class has the poor design choice of its toString applying a default time zone when generating a String. So it seems like it has a time zone when in fact it does not (except one buried underneath that is ignored for regular use). Confusing, yes. Avoid it.
java.time
Instead use java.time built into Java 8 and later.
First parse as a LocalDateTime without any time zone or offset.
LocalDateTime ldt = LocalDateTime.parse( "1995-12-31T23:59:59Z" );
Apply a time zone or offset-from-UTC to give this LocalDateTime meaning, to make it an actual moment on the timeline. You have to know, or ask, what time zone or offset was intended by this string as no indication was embedded. For this example, I will arbitrarily assume Québec.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
Your desired output has a Z on the end, for Zulu which means UTC.
In java.time an Instant represents a moment on the timeline in UTC. You can extract an Instant from the ZonedDateTime.
Instant instant = zdt.toInstant();
The Instant class’ toString method generates a string in your desired format. That format is one of the standard ISO 8601 formats.
String output = instant.toString();
Half-Open
I happened to notice that your example value was trying to get the end of 1995. There is a better way to do such search or comparison criteria.
In date-time work, the best practice is called Half-Open where the beginning of a span of time is inclusive while the ending is exclusive. So a week starts on Monday and runs up to, but not including, the next Monday.
Defining a year means starting at the first moment of the first day of 1995 and running up to but not including the first moment of the first day of the following year, 1996. Searching for any values within that range is done not with a BETWEEN but as: ( someEvent >= firstMomentOf1995 AND someEvent < firstMomentOf1996 ) ( not <= ).

Categories