I have a requirement to
Save and retrieve the date in GMT timezone (date should be converted to String). So, if user saves date 10/10/2017 23:05, that will be saved as 10/11/2017 4:05 (5 hours ahead if saved in CST time for e.g.) in DB.
While retrieving and presenting the date to UI, it should show as 10/10/2017 23:05 for CST users.
Also, need to verify a function to know if the date needs to be shown in US/Non-US date format (dd/MM/YYYY vs mm/DD/YYYY).
To achieve this, I have coded below snippets, however is not yielding the required result. It is storing the value 10/11/2017 4:05, however, when presenting to US, i.e. getting value/ refreshing the page, its adding 5 more hours. Removed exceptions and other unnecessary code to make it simple:
public class DatetoString implements Serializable
{
private final DateFormat dateFormatter = createDateFormatter();
// Sets Date to model
public void setTypedValue(final Object val)
{
final String dateValue;
String dateTimeFormat = BooleanUtils.isFalse(getUSDateFormatConfig()) ? "dd/MM/yyyy HH:mm" : "MM/dd/yyyy HH:mm";
DateFormat df = new SimpleDateFormat(dateTimeFormat);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
Date singleDate = (Date) df.parse(val.toString());
dateValue = dateFormatter.format(singleDate);
model.setValue(dateValue.toString());
// Other code..
}
// Retrieves date from model
public Object getTypedValue()
{
final Object result;
String dateValue = model.iterator().next().getValue();
String dateTimeFormat = BooleanUtils.isFalse(getUSDateFormatConfig()) ? "dd/MM/yyyy HH:mm" : "MM/dd/yyyy HH:mm";
DateFormat df = new SimpleDateFormat(dateTimeFormat);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
Date singleDate = (Date) df.parse(dateValue);
result = dateFormatter.format(singleDate);
return result;
}
private DateFormat createDateFormatter()
{
final DateFormat result = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
result.setTimeZone(TimeZone.getTimeZone("GMT"));
return result;
}
}
java.time
You are using terrible old date-time classes that are troublesome, confusing, and poorly designed. They are now legacy, supplanted by the java.time classes. Avoid Date, Calendar, SimpleDateFormat, and such.
Use real time zones
By CST did you mean Central Standard Time or China Standard Time?
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/Chicago" );
Confirm time zone with user
If the time zone is critical for your work, you must confirm which zone was intended by their input. There are ways to guess at the zone or detect a default, but where important, make the zone part of your data-entry along with the date and the time-of-day. You can present a list from which they choose, or let them input a string name.
Ditto for Locale (discussed below). You can guess, but if critical, ask.
Parse and assemble
Save and retrieve the date in GMT timezone (date should be converted to String). So, if user saves date 10/10/2017 23:05, that will be saved as 10/11/2017 4:05 (5 hours ahead if saved in CST time for e.g.) in DB.
Parse the user input as a LocalDate and LocalTime using a DateTimeFormatter.
In real work you would add try-catch to capture DateTimeParseException thrown by faulty user input.
DateTimeFormatter fDate = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( inputDate , f ) ;
DateTimeFormatter fTime = DateTimeFormatter.ISO_LOCAL_TIME ;
LocalTime lt = LocalTime.parse( inputTime , f ) ;
Combine, and specify a time zone to get a ZonedDateTime object.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Adjust to UTC by extracting an Instant which is always in UTC by definition. Same moment, same point on the timeline, but viewed through the lens of a different wall-clock.
Instant instant = zdt.toInstant() ;
Database
Persist to your database, in a column of type TIMESTAMP WITH TIME ZONE. The other type WITHOUT ignores any time zone or offset-from-UTC information and is most definitely not what you want to track actual moments in time.
myPreparedStatement.setObject( … , instant ) ;
Retrieve from database.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
While retrieving and presenting the date to UI, it should show as 10/10/2017 23:05 for CST users.
Adjust into whatever time zone the user expects/desires.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; // Or "America/Chicago" or "America/Winnipeg" etc.
ZonedDateTime zdt = instant.atZone( z ) ;
Generate textual representation
Also, need to verify a function to know if the date needs to be shown in US/Non-US date format (dd/MM/YYYY vs mm/DD/YYYY).
Likewise, when generating text to represent that moment, automatically localize with whatever Locale the user expects/desires.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.FRANCE ; // Or Locale.US etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ).withLocale( l ) ;
String output = zdt.format( f ) ;
Note that Locale and time zone are orthogonal, unrelated and separate. You can have a French-speaking clerk in Morocco who is tracking a customer's delivery in India. So the moment is stored in UTC in the database running on a server in Canada, exchanged between database and other components in UTC, adjusted into India time zone to address the perspective of customer receiving delivery, and localized to French for reading by the user in Morocco.
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.
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
java.time
I agree wholeheartedly with Basil Bourque’s thorough and very knowledgeable answer. That your formats are old, has nothing to do with using the old and outdated date and time classes. Using the modern ones would lead to code that comes more naturally, and it would be easier to avoid problems like the one you are asking about. Also use time zone names in the format region/city, and beware that your JVM’s default time zone setting may be changed during runtime by other programs running in the same JVM.
EDIT: I didn’t want to spoil it by providing the code from the outset, but now you have solved your problem, for anyone reading along, here it is:
private static final DateTimeFormatter storeFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
private static final DateTimeFormatter usDisplayFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
private static final DateTimeFormatter internationalDisplayFormatter
= DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
private ZoneId userTimeZone = ZoneId.of("America/Rosario");
/** Sets Date to model */
public void setTypedValue(final Object val)
{
DateTimeFormatter parseFormatter = isUSDateFormatConfig()
? usDisplayFormatter : internationalDisplayFormatter;
final String dateValue = LocalDateTime.parse(val.toString(), parseFormatter)
.atZone(userTimeZone)
.withZoneSameInstant(ZoneOffset.UTC)
.format(storeFormatter);
model.setValue(dateValue);
// Other code..
}
/** Retrieves date from model */
public Object getTypedValue()
{
String dateValue = model.iterator().next().getValue();
DateTimeFormatter displayFormatter = isUSDateFormatConfig()
? usDisplayFormatter : internationalDisplayFormatter;
final Object result = LocalDateTime.parse(dateValue, storeFormatter)
.atOffset(ZoneOffset.UTC)
.atZoneSameInstant(userTimeZone)
.format(displayFormatter);
return result;
}
I called setTypedValue("10/29/2017 21:30"), and the date-time was stored as 10/30/2017 00:30:00. I was able to retrieve it as both 10/29/2017 21:30 in the US and 29/10/2017 21:30 outside.
For now I have hardcoded the user’s time zone as America/Rosario just to demonstrate the use of the region/city format. Instead of the userTimeZone variable you may of course use ZoneId.systemDefault(), but as I said, this may be changed under your feet by other programs running in the same JVM.
If you wanted to modernize your user interface, you could use DateTimeFormatter.ofLocalizedDateTime() instead of the hardcoded display formats, as also mentioned by Basil Bourque.
What was wrong in your code?
It seems to me that in your code in the question you are doing similar conversions in setTypedValue and getTypedValue. Shouldn’t you do opposite conversions? I would suppose that in getTypedValue you should use dateFormatter (the final instance variable) for parsing from GMT and then a formatter using local time zone (not GMT) for formatting.
Minor points:
You don’t need to cast the return value from df.parse() in any of the two places you are doing that, since it is already declared that that method returns a Date.
You don’t need to call toString() on dateValue since it is already declared a String, so the call will just return the same String again.
Related
I've tried all sorts of different conversions with different Java formatters but I'm still not having any luck with something that seems simple.
I have a string that is a date/time in UTC. I'm trying to convert that to another time zone. Is any one able to tell me why the below isn't working? The time zone is changing but it's not changing the right way.
Updated: (though it doesn't seem like I'm setting the time zone to UTC properly as the conversion isn't correct either).
String dateInput = "2021-02-16 20:57:43";
SimpleDateFormat mdyUtc = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
mdyUtc.setTimeZone(TimeZone.getTimeZone("UTC");
Date utcOutput = mdyUtc.parse(dateInput);
SimpleDateFormat mdyOffset = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
mdyOffset.setTimeZone(TimeZone.getTimeZone("GMT-10:00");
Date localOutput = mdyOffset.parse(dateInput);
System.out.print("UTC date = " + utcOutput);
System.out.print("Changed date = " + localOutput);
Output:
UTC date = Tue Feb 16 15:57:43 EST 2021
Changed date = Wed Feb 17 01:57:43 EST 2021
java.time
The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.
Using the modern date-time API:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String dateInput = "2021-02-16 20:57:43";
// Replace ZoneId.systemDefault() with ZoneOffset.UTC if this date-time is in UTC
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
.withZone(ZoneId.systemDefault());
ZonedDateTime zdt = ZonedDateTime.parse(dateInput, dtf);
ZonedDateTime result = zdt.withZoneSameInstant(ZoneId.of("GMT-10:00"));
System.out.println(result);
}
}
Output:
2021-02-16T10:57:43-10:00[GMT-10:00]
ONLINE DEMO
Learn more about the modern date-time API from Trail: Date Time.
Can I get java.util.Date from ZonedDateTime?
If at all you need to use java.util.Date, you can convert ZonedDateTime into it as follows:
Date date = Date.from(result.toInstant());
Note that the java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat and obtain the formatted string from it.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
tl;dr
LocalDateTime // Represent a date with time-of-day but lacking the context of a time zone or offset-from-UTC.
.parse( // Interpret some text in order to build a date-time object.
"2021-02-16 20:57:43".replace( " " , "T" ) // Convert to standard ISO 8601 string to parse by default without needing to specify a formatting pattern.
) // Returns a `LocalDateTime` object.
.atOffset( // Place that date with time into the context of an offset. Determines a moment, a specific point on the timeline.
ZoneOffset.UTC // A constant for an offset of zero hours-minutes-seconds.
) // Returns an `OffsetDateTime` object.
.atZoneSameInstant( // Adjust the view of this moment as seen in the wall-clock time of some other time zone. Still the same moment, same point on the timeline.
ZoneId.of( "Pacific/Honolulu" ) // Use a time zone, if known, rather than a mere offset.
) // Returns a `ZonedDateTime` object.
.toString() // Generate text representing this moment in standard ISO 8601 format extended to append the time zone name in square brackets.
See this code run live at IdeOne.com.
2021-02-16T10:57:43-10:00[Pacific/Honolulu]
Details
The Answer by Avinash is correct, using a DateTimeFormatter with an assigned ZoneId. That works, but I prefer keeping the zone assignment separate from the formatter, to be more explicit to someone reading the code. This is only about my preference, not about correctness; both Answers are equally correct.
Parse your input as a LocalDateTime, as the input represents a date with time-of-day but lacks any indication of offset or time zone.
By default, the java.time classes use standard text formats defined in ISO 8601. If an input complies, no need to specify a formatting pattern. To comply, replace your input’s SPACE character in the middle with a T.
String input = "2021-02-16 20:57:43".replace( " " , "T" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
You said you know for certain that input was meant to represent a date with time as seen in UTC, having an offset-from-UTC of zero hours-minutes-seconds. So we can apply an offset of zero using ZoneOffset to produce a OffsetDateTime.
Also, I suggest you educate the publisher of your data feed about using ISO 8601 formats to communicate that offset-of-zero fact by appending a Z (as well as using T in the middle).
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ; // Place date with time into context of an offset of zero.
Lastly, you said you want to adjust that moment to another time zone. Apply a ZoneId to get a ZonedDateTime object.
Actually, you specified an offset of "GMT-10:00". But it is better to use a time zone if known rather than a mere offset. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
I will guess you want Hawaii time, Pacific/Honolulu.
ZoneId z = ZoneId.of( "Pacific/Honolulu" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
The java.util.Date API is deprecated; you should look into the new Date and Time APIs around LocalTime et al.
That said, if you want to keep the old code: It is a bit brittle. Your initial date input does not specify a time zone, so you'll probably get the system's time zone. You should specify a time zone --- if the expected input is UTC, say so.
Then you need to specify the time zone either in an hour offset or with a name, not both.
When I change your code to use
mdyOffset.setTimeZone(TimeZone.getTimeZone("-10:00"));
I get
Changed date = Tue Feb 16 14:57:43 CST 2021
which seems to fit, as I'm on CST (currently 6 hours after GMT), so 20:57:43 minus 6 is 14:57:43. Again, this is displayed in my local time zone. You may have to use a DateFormat to adjust the output as needed.
For a REST web service, I need to return dates (no time) with a time zone.
Apparently there is no such thing as a ZonedDate in Java (only LocalDate and ZonedDateTime), so I'm using ZonedDateTime as a fallback.
When converting those dates to JSON, I use DateTimeFormatter.ISO_OFFSET_DATE to format the date, which works really well:
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE;
ZonedDateTime dateTime = ZonedDateTime.now();
String formatted = dateTime.format(formatter);
2018-04-19+02:00
However, attempting to parse back such a date with...
ZonedDateTime parsed = ZonedDateTime.parse(formatted, formatter);
... results in an Exception:
java.time.format.DateTimeParseException: Text '2018-04-19+02:00' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {OffsetSeconds=7200},ISO resolved to 2018-04-19 of type java.time.format.Parsed
I also tried ISO_DATE and ran into the same problem.
How can I parse such a zoned date back?
Or is there any other type (within the Java Time API) I'm supposed to use for zoned dates?
The problem is that ZonedDateTime needs all the date and time fields to be built (year, month, day, hour, minute, second, nanosecond), but the formatter ISO_OFFSET_DATE produces a string without the time part.
When parsing it back, there are no time-related fields (hours, minutes, seconds) and you get a DateTimeParseException.
One alternative to parse it is to use a DateTimeFormatterBuilder and define default values for the time fields. As you used atStartOfDay in your answer, I'm assuming you want midnight, so you can do the following:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date and offset
.append(DateTimeFormatter.ISO_OFFSET_DATE)
// default values for hour and minute
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.toFormatter();
ZonedDateTime parsed = ZonedDateTime.parse("2018-04-19+02:00", fmt); // 2018-04-19T00:00+02:00
Your solution also works fine, but the only problem is that you're parsing the input twice (each call to formatter.parse will parse the input again). A better alternative is to use the parse method without a temporal query (parse only once), and then use the parsed object to get the information you need.
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE;
// parse input
TemporalAccessor parsed = formatter.parse("2018-04-19+02:00");
// get data from the parsed object
LocalDate date = LocalDate.from(parsed);
ZoneId zone = ZoneId.from(parsed);
ZonedDateTime restored = date.atStartOfDay(zone); // 2018-04-19T00:00+02:00
With this solution, the input is parsed only once.
tl;dr
Use a time zone (continent/region) rather than a mere offset-from-UTC (hours-minutes-seconds). For any particular zone, the offset is likely to change over time.
Combine the two to determine a moment.
LocalDate.parse(
"2018-04-19"
)
.atStartOfDay(
ZoneId.of( "Europe/Zurich" )
) // Returns a `ZonedDateTime` object.
2018-04-19T00:00+02:00[Europe/Zurich]
From your REST service, either:
Return the date and zone separately (either with a delimiter or as XML/JSON), or,
Return the start of day as that is likely the intended outcome of a date with a time zone.
Separate your text inputs
The solution in the Answer by Walser is effectively treating the string input as a pair of string inputs. First the date-only part is extracted and parsed. Second, the offset-from-UTC part is extracted and parsed. So, the input is parsed twice, each time ignoring the opposite half of the string.
I suggest you make this practice explicit. Track the date as one piece of text, track the offset (or, better, a time zone) as another piece of text. As the code in that other Answer demonstrates, there is no real meaning to a date with zone until you take the next step of determining an actual moment such as the start of day.
String inputDate = "2018-04-19" ;
LocalDate ld = LocalDate.parse( inputDate ) ;
String inputOffset = "+02:00" ;
ZoneOffset offset = ZoneOffset.of( inputOffset) ;
OffsetTime ot = OffsetTime.of( LocalTime.MIN , offset ) ;
OffsetDateTime odt = ld.atTime( ot ) ; // Use `OffsetDateTime` & `ZoneOffset` when given a offset-from-UTC. Use `ZonedDateTime` and `ZoneId` when given a time zone rather than a mere offset.
odt.toString(): 2018-04-19T00:00+02:00
As you can see, the code is simple, and your intent is obvious.
And no need to bother with any DateTimeFormatter object nor formatting patterns. Those inputs conform with ISO 8601 standard formats. The java.time classes use those standard formats by default when parsing/generating strings.
Offset versus Zone
As for applying the date and offset to get a moment, you are conflating a offset-from-UTC with a time zone. An offset is simply a number of hours, minutes, and seconds. No more, no less. In contrast, a time zone is a history of the past, present, and future changes in offset used by the people of a particular region.
In other words, the +02:00 happens to be used by many time zones on many dates. But in a particular zone, such as Europe/Zurich, other offsets may be used on other dates. For example, adopting the silliness of Daylight Saving Time (DST) means a zone will be spending half the year with one offset and the other half with a different offset.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Europe/Zurich" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
zdt.toString(): 2018-04-19T00:00+02:00[Europe/Zurich]
So I suggest you track two strings of input:
Date-only (LocalDate): YYYY-MM-DD such as 2018-04-19
Proper time zone name (ZoneId): continent/region such as Europe/Zurich
Combine.
ZonedDateTime zdt =
LocalDate.parse( inputDate )
.atStartOfDay( ZoneId.of( inputZone ) )
;
Note: The ZonedDateTime::toString method generates a String in a format that wisely extends the standard ISO 8601 format by appending the name of the time zone in square brackets. This rectifies a huge oversight made by the otherwise well-designed standard. But you can only return such a string by your REST service if you know your clients can consume it.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I found the solution (using TemporalQueries):
parse the date and zone separately, and restore the zoned date using that information:
LocalDate date = formatter.parse(formatted, TemporalQueries.localDate());
ZoneId zone = formatter.parse(formatted, TemporalQueries.zone());
ZonedDateTime restored = date.atStartOfDay(zone);
I wanted to convert a date from one time zone to another, using SimpleDateFormat class in java. But somehow it is generating different results which are suppose to be in the same TimeZone.
Here is a test case, and its generating one result as IST and other one as GMT. i think it should be generating only GMT's for both cases.
public class TestOneCoreJava {
public static void main(String[] args) throws ParseException {// Asia/Calcutta
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a");
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Oct-10 10:00:00 AM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
//------Output--
//26-Nov-10 GMT
//02-Oct-10 IST
}
public static String getDateStringToShow(Date date,
String sourceTimeZoneId, String targetTimeZoneId, boolean includeTime) {
String result = null;
// System.out.println("CHANGING TIMEZONE:1 "+UnitedLexConstants.SIMPLE_FORMAT.format(date));
String date1 = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a").format(date);
SimpleDateFormat sourceTimeZoneFormat = new SimpleDateFormat("Z");
sourceTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(sourceTimeZoneId));
date1 += " " + sourceTimeZoneFormat.format(date);
// Changed from 'Z' to 'z' to show IST etc, in place of +5:30 etc.
SimpleDateFormat targetTimeZoneFormat = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a z");
targetTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
SimpleDateFormat timeZoneDayFormat = null;
if (includeTime) {
timeZoneDayFormat = targetTimeZoneFormat;
} else {
timeZoneDayFormat = new SimpleDateFormat("dd-MMM-yy z");
}
timeZoneDayFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
try {
result = timeZoneDayFormat.format(targetTimeZoneFormat.parse(date1));
// System.out.println("CHANGING TIMEZONE:3 "+result);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
}
tl;dr
Use modern java.time classes, specifically ZonedDateTime and ZoneId. See Oracle Tutorial.
ZonedDateTime // Represent a date and time-of-day in a specific time zone.
.now( // Capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" ) // Specify time zone using proper name in `Continent/Region` format. Never use 3-4 letter pseudo-zone such as IST or PST or EST.
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust from one time zone to another. Same point on the timeline, same moment, but different wall-clock time.
ZoneId.of( "Africa/Tunis" )
) // Returns a new fresh `ZonedDateTime` object rather than altering/“mutating” the original, per immutable objects pattern.
.toString() // Generate text in standard ISO 8601 format, extended to append name of zone in square brackets.
2018-09-18T21:47:32.035960+01:00[Africa/Tunis]
For UTC, call ZonedDateTime::toInstant.
Avoid 3-Letter Time Zone Codes
Avoid those three-letter time zone codes. They are neither standardized nor unique. For example, your use of "IST" may mean India Standard Time, Irish Standard Time, and maybe others.
Use proper time zone names. The definition of time zones and their names change frequently, so keep your source up-to-date. For example the old "Asia/Calcutta" is now "Asia/Kolkata". And not just names; governments are notorious for changing the rules/behavior of a time zone, occasionally at the last minute.
Avoid j.u.Date
Avoid using the bundled java.util.Date and Calendar classes. They are notoriously troublesome and will be supplanted in Java 8 by the new java.time.* package (which was inspired by Joda-Time).
java.time
Instant
Learn to think and work in UTC rather than your own parochial time zone. Logging, data-exchange, and data-storage should usually be done in UTC.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-09-18T20:48:43.354953Z
ZonedDateTime
Adjust into a time zone. Same moment, same point on the timeline, different wall-clock time. Apply a ZoneId (time zone) to get a ZonedDateTime object.
ZoneId zMontreal = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontreal = instant.atZone( zMontreal ) ; // Same moment, different wall-clock time.
We can adjust again, using either the Instant or the ZonedDateTime.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdtMontreal.withZoneSameInstant( zKolkata ) ;
ISO 8601
Calling toString on any of these classes produce text in standard ISO 8601 class. The ZonedDateTime class extends the standard wisely by appending the name of the time zone in square brackets.
When exchanging date-time values as text, always use ISO 8601 formats. Do not use custom formats or localized formats as seen in your Question.
The java.time classes use the standard formats by default for both parsing and generating strings.
Instant instant = Instant.parse( "2018-01-23T01:23:45.123456Z" ) ;
Using standard formats avoids all that messy string manipulation seen in the Question.
Adjust to UTC
You can always take a ZonedDateTime back to UTC by extracting a Instant.
Instant instant = zdtKolkata.toInstant() ;
DateTimeFormatter
To represent your date-time value in other formats, search Stack Overflow for DateTimeFormatter class. You will find many examples and discussions.
UPDATE: The Joda-Time project is now in maintenance-mode, and advises migration to the java.time classes. I am leaving this section intact as history.
Joda-Time
Beware of java.util.Date objects that seem like they have a time zone but in fact do not. In Joda-Time, a DateTime does indeed know its assigned time zone. Generally should specify a desired time zone. Otherwise, the JVM's default time zone will be assigned.
Joda-Time uses mainly immutable objects. Rather than modify an instance, a new fresh instance is created. When calling methods such as toDateTime, a new fresh DateTime instance is returned leaving the original object intact and unchanged.
//DateTime now = new DateTime(); // Default time zone automatically assigned.
// Convert a java.util.Date to Joda-Time.
java.util.Date date = new java.util.Date();
DateTime now = new DateTime( date ); // Default time zone automatically assigned.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime nowIndia = now.toDateTime( timeZone );
// For UTC/GMT, use built-in constant.
DateTime nowUtcGmt = nowIndia.toDateTime( DateTimeZone.UTC );
// Convert from Joda-Time to java.util.Date.
java.util.Date date2 = nowIndia.toDate();
Dump to console…
System.out.println( "date: " + date );
System.out.println( "now: " + now );
System.out.println( "nowIndia: " + nowIndia );
System.out.println( "nowUtcGmt: " + nowUtcGmt );
System.out.println( "date2: " + date2 );
When run…
date: Sat Jan 25 16:52:28 PST 2014
now: 2014-01-25T16:52:28.003-08:00
nowIndia: 2014-01-26T06:22:28.003+05:30
nowUtcGmt: 2014-01-26T00:52:28.003Z
date2: Sat Jan 25 16:52:28 PST 2014
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
When dealing with Timezone issues in Google API. I came across such kind of issues.
Look at this piece of code of yours:-
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Nov-10 10:00:00 AM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
If i give above as input it will run fine the way we want to.
If you still want to go with this way then you have to perform calculation according to your need.
Like adjusting the time Mathematically and things similar to it.
Or a Simple fix for your case will be something like this
SimpleDateFormat d =new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
d.setTimeZone(TimeZone.getTimeZone("Europe/Dublin"));
Date firsttime = d.parse("2013-12-19T03:31:20");
Date seondtime = d.parse("2013-12-19T10:00:00");
System.out.println(getDateStringToShow(firsttime,"Asia/Calcutta",
"Europe/Dublin", false));
System.out.println(getDateStringToShow(seondtime,"Asia/Calcutta",
"Europe/Dublin", false));
My suggestion will be to refer JODA API . More preferrable over Old School Date.
I am finding the current time using Date date3 = Calendar.getInstance().getTime();
This gives me Thu Oct 25 11:42:22 IST 2012
Now I want my Date to be in the format 2012.10.25 and that too as a Date object and not a string.
I tried using the below code
DateFormat df = new SimpleDateFormat("yyyy.MM.dd");
Date startDate = df.parse(c_date1);
But when I finally use System.out.println(startDate.toString()); it again gives me
Thu Oct 25 00:00:00 IST 2012. that is practically because the toString() function has been implemented in a way to show this format.
So is there any other way to get the date as 2012.10.25 and that too as the Date format. Date object is required because it is to be saved in db as a date field.
you need to use df.format(Date) method to get date in required format
Date date3 = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
System.out.println(df.format(date3));
Date date3 = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd");
java.sql.Date date = null;
try {
date =new java.sql.Date(df.parse(df.format(date3)).getTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(date);
tl;dr
Avoid terrible legacy date-time classes (Date, SimpleDateFormat). Use only the modern java.time classes.
LocalDate.now( // Instantiate a date-only object, without time-of-day and without time zone.
ZoneId.of( "India/Kolkata" ) // Capture the current date, “today”, as seen by the people in a certain region (a time zone). For any given moment, the date varies around the globe by zone.
)
.format( // Generate a String whose text represents the date-time value of our `LocalDate` object.
DateTimeFormatter.ofPattern( "uuuu.MM.dd" ) // Specify your desired formatting pattern.
)
2012.10.25
To insert the date-only value for the current date into your database:
myPreparedStatement.setObject(
… ,
LocalDate.now( ZoneId.of( "India/Kolkata" ) )
) ;
Confusing date-time value with a String
Date-time values do not have a “format”. Only strings have a format. Do not conflate the two. A date-time object can be instantiated by parsing a String. And a date-time object can generate a String to represent its value textually. But the date-time object and such strings remain separate and distinct.
it again gives me Thu Oct 25 00:00:00 IST 2012. that is practically because the toString() function has been implemented in a way to show this format.
No, the toString method does not “show” this format. That wording implies the format lives within the Date object. But the format does not live inside the Date object – the Date has no “format” at all. The toString method generates a String whose characters are arranged into this format.
Confusing date-only with date-time
You seem to interesting in a date-only values, without a time-of-day and without a time zone. If so, use the LocalDate class.
Create a LocalDate object for your desired value by parsing a string. Easiest to use the standard ISO 8601 format used by default in the java.time classes: YYYY-MM-DD.
String input = "2012-10-25" ;
LocalDate ld = LocalDate.parse( input ) ; // No need to specify a formatting pattern, as ISO 8601 format used by default.
Your input string is in a non-standard format. Happens to be the same year-month-day order, so I would just replace the FULL STOP dots with hyphens.
String input = "2012.10.25".replace( "." , "-" ) ; // Convert from custom format to standard ISO 8601 format.
LocalDate ld = LocalDate.parse( input ) ; // No need to specify a formatting pattern, as ISO 8601 format used by default.
Or specify a formatting pattern.
String input = "2012.10.25" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu.MM.dd" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
Use that same formatter object to generate a string.
String output = ld.format( f ) ; // Generate a string in this custom format.
Current date
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( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). 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( 1986 , Month.FEBRUARY , 23 ) ;
Database
As of JDBC 4.2 and later, we can directly exchange java.time objects with a database.
If storing this LocalDate object to a SQL-standard DATE column:
myPreparedStatment.setObject( … , ld ) ;
And retrieval:
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
If storing to a SQL-standard TIMESTAMP WITH TIME ZONE column, we need a date-time value rather than our date-only value. Perhaps you want to use the first moment of the day on that date? If so, let java.time determine that first moment. Do not assume 00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at another time such as 01:00.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // First moment of the day for that date for the people in India.
Most databases store zoned date-time moments by adjusting into UTC. Your JDBC driver and database may do that for you, or you can extract a UTC value (Instant) from your ZonedDateTime.
Instant instant = zdt.toInstant() ; // Adjust from zoned time to UTC time.
myPreparedStatment.setObject( … , instant ) ;
And retrieval:
Instant instant = myResultSet.getObject( … , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Date object do not have any format. i.e. you can not convert any Date object into perticular format. Becuase it has its own to string format which will return when you print any date. You can convert any string format only.
You can convert or construct any Date Object from date string of the specific format. but that date object will not be in a specific format.
Your question is just like asking:
I have an int variable of value 1234567, and I want it to store as "1,234,567" in that variable.
It is simply not reasonable.
How a value is stored, is nothing to do with how the value is presented.
If you want to save a date in db in given date format the you can use
DateFormat df = new SimpleDateFormat("yyyy.MM.dd");
Date date3 = Calendar.getInstance().getTime();
String startDate = df.format(date3);
try {
java.sql.Date date = new java.sql.Date(df.parse(startDate).getTime());
System.out.println(date);
} catch (ParseException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
It's very simple
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
format.parse(dateObject.toString());
I am using following code to get date in "dd/MM/yyyy HH:mm:ss.SS" format.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: "+strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
System.out.println("Current date in Date Format: "+date);
}
}
and am getting following output
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: Thu Jan 05 21:10:17 IST 2012
Kindly suggest what i should do to display the date in same string format(dd/MM/yyyy HH:mm:ss.SS) i.e i want following output:
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: 05/01/2012 21:10:17.287
Kindly suggest
SimpleDateFormat
sdf=new SimpleDateFormat("dd/MM/YYYY hh:mm:ss");
String dateString=sdf.format(date);
It will give the output 28/09/2013 09:57:19 as you expected.
For complete program click here
You can't - because you're calling Date.toString() which will always include the system time zone if that's in the default date format for the default locale. The Date value itself has no concept of a format. If you want to format it in a particular way, use SimpleDateFormat.format()... using Date.toString() is almost always a bad idea.
The following code gives expected output. Is that what you want?
import java.util.Calendar;
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) throws Exception {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: " + strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
String string = sdf1.format(date);
System.out.println("Current date in Date Format: " + string);
}
}
Use:
System.out.println("Current date in Date Format: " + sdf.format(date));
tl;dr
Use modern java.time classes.
Never use Date/Calendar/SimpleDateFormat classes.
Example:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc.
)
.truncatedTo( // Lop off finer part of this value.
ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object.
) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original.
.format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output.
) // Returns a `String`.
.replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
The modern approach uses java.time classes that years ago supplanted the terrible old date-time classes such as Calendar & SimpleDateFormat.
want current date and time
Capture the current moment in UTC using Instant.
Instant instant = Instant.now() ;
To view that same moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Or, as a shortcut, pass a ZoneId to the ZonedDateTime.now method.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
The java.time classes use a resolution of nanoseconds. That means up to nine digits of a decimal fraction of a second. If you want only three, milliseconds, truncate. Pass your desired limit as a ChronoUnit enum object.
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.truncatedTo(
ChronoUnit.MILLIS
)
in “dd/MM/yyyy HH:mm:ss.SS” format
I recommend always including the offset-from-UTC or time zone when generating a string, to avoid ambiguity and misunderstanding.
But if you insist, you can specify a specific format when generating a string to represent your date-time value. A built-in pre-defined formatter nearly meets your desired format, but for a T where you want a SPACE.
String output =
zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )
;
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
Never exchange date-time values using text intended for presentation to humans.
Instead, use the standard formats defined for this very purpose, found in ISO 8601.
The java.time use these ISO 8601 formats by default when parsing/generating strings.
Always include an indicator of the offset-from-UTC or time zone when exchanging a specific moment. So your desired format discussed above is to be avoided for data-exchange. Furthermore, generally best to exchange a moment as UTC. This means an Instant in java.time. You can exchange a Instant from a ZonedDateTime, effectively adjusting from a time zone to UTC for the same moment, same point on the timeline, but a different wall-clock time.
Instant instant = zdt.toInstant() ;
String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
This ISO 8601 format uses a Z on the end to represent UTC, pronounced “Zulu”.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Here's a simple snippet working in Java 8 and using the "new" date and time API LocalDateTime:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss.SS");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
The output in your first printline is using your formatter. The output in your second (the date created from your parsed string) is output using Date#toString which formats according to its own rules. That is, you're not using a formatter.
The rules are as per what you're seeing and described here:
http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#toString()
Disclaimer: this answer does not endorse the use of the Date class (in fact it’s long outdated and poorly designed, so I’d rather discourage it completely). I try to answer a regularly recurring question about date and time objects with a format. For this purpose I am using the Date class as example. Other classes are treated at the end.
You don’t want to
You don’t want a Date with a specific format. Good practice in all but the simplest throw-away programs is to keep your user interface apart from your model and your business logic. The value of the Date object belongs in your model, so keep your Date there and never let the user see it directly. When you adhere to this, it will never matter which format the Date has got. Whenever the user should see the date, format it into a String and show the string to the user. Similarly if you need a specific format for persistence or exchange with another system, format the Date into a string for that purpose. If the user needs to enter a date and/or time, either accept a string or use a date picker or time picker.
Special case: storing into an SQL database. It may appear that your database requires a specific format. Not so. Use yourPreparedStatement.setObject(yourParamIndex, yourDateOrTimeObject) where yourDateOrTimeObject is a LocalDate, Instant, LocalDateTime or an instance of an appropriate date-time class from java.time. And again don’t worry about the format of that object. Search for more details.
You cannot
A Date hasn’t got, as in cannot have a format. It’s a point in time, nothing more, nothing less. A container of a value. In your code sdf1.parse converts your string into a Date object, that is, into a point in time. It doesn’t keep the string nor the format that was in the string.
To finish the story, let’s look at the next line from your code too:
System.out.println("Current date in Date Format: "+date);
In order to perform the string concatenation required by the + sign Java needs to convert your Date into a String first. It does this by calling the toString method of your Date object. Date.toString always produces a string like Thu Jan 05 21:10:17 IST 2012. There is no way you could change that (except in a subclass of Date, but you don’t want that). Then the generated string is concatenated with the string literal to produce the string printed by System.out.println.
In short “format” applies only to the string representations of dates, not to the dates themselves.
Isn’t it strange that a Date hasn’t got a format?
I think what I’ve written is quite as we should expect. It’s similar to other types. Think of an int. The same int may be formatted into strings like 53,551, 53.551 (with a dot as thousands separator), 00053551, +53 551 or even 0x0000_D12F. All of this formatting produces strings, while the int just stays the same and doesn’t change its format. With a Date object it’s exactly the same: you can format it into many different strings, but the Date itself always stays the same.
Can I then have a LocalDate, a ZonedDateTime, a Calendar, a GregorianCalendar, an XMLGregorianCalendar, a java.sql.Date, Time or Timestamp in the format of my choice?
No, you cannot, and for the same reasons as above. None of the mentioned classes, in fact no date or time class I have ever met, can have a format. You can have your desired format only in a String outside your date-time object.
Links
Model–view–controller on Wikipedia
All about java.util.Date on Jon Skeet’s coding blog
Answers by Basil Bourque and Pitto explaining what to do instead (also using classes that are more modern and far more programmer friendly than Date)
If you are using JAVA8 API then this code will help.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeString = LocalDateTime.now().format(formatter);
System.out.println(dateTimeString);
It will print the date in the given format.
But if you again create a object of LocalDateTime it will print the 'T' in between the date and time.
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime.toString());
So as mentioned in earlier posts as well, the representation and usage is different.
Its better to use "yyyy-MM-dd'T'HH:mm:ss" pattern and convert the string/date object accordingly.
use
Date date = new Date();
String strDate = sdf.format(date);
intead Of
Calendar cal = Calendar.getInstance();
String strDate = sdf.format(cal.getTime());
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Date date = new Date(System.currentTimeMillis());
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS",
Locale.ENGLISH);
String strDate = format.format(date);
System.out.println("Current date in String Format: "+strDate);
}
}
use this code u will get current date in expected string format