I'd like to parse string in MM-dd format to java date. Since year is not specified, parsed date should be in current year. Only valid date string should be parsed, so I should use setLenient(false) in SimpleDateFormat.
public static Date parseDate(String ds) throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("MM-dd");
df.setLenient(false);
Date d = df.parse(ds);
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
cal.setTime(d);
cal.set(Calendar.YEAR, year);
return cal.getTime();
}
This seems to work well until I pass an argument "02-29". This year(2012) is leap year and 2012-02-29 is valid date, "02-29" should have been parsed successfully.
I found that when I don't specify year part in SimpleDateFormat, it parse to year 1970. And 1970 is not a leap year, "02-29" fails to parse. So, parsing to date of year 1970 and set current year after parsing strategy is not perfect.
What is the best way to parse MM-dd format string to date (date should be set to current year) in Java?
PS1: I searched this topic and found many questions and answers in this site, but I couldn't find the satisfactory answer.
PS2: df.setLenient(false); is important because only valid date string should be parsed successfully. Invalid date strings like "01-32", "02-30", etc. shouldn't be parsed.
Thanks in advance.
tl;dr
parse string in MM-dd format … in current year
MonthDay // Represent a month-day as such, in a class designed for that purpose.
.parse ( // By default parses strings in standard ISO 8601 format.
"--" + "02-29" // Prepending a double-hyphen to make this input comply with ISO 8601.
) // Returns a `MonthDay` object.
.atYear( // Get the date of this month-day in a specified year.
Year.now( ZoneId.of( "Asia/Tokyo" ) ).getValue() // Getting current year requires a time zone.
) // Returns a `LocalDate` object, a year-month-day without time zone and without time-of-day.
See this code run live at IdeOne.com.
2019-02-28
java.time
The modern solution uses the industry-leading java.time classes built into Java 8 and later, with a back-port available for Java 6 & 7 and early Android.
MonthDay
A month-with-day is represented by the appropriately-named MonthDay class.
The standard format for a month-day defined in ISO 8601 is a --MM-DD where the first dash is a placeholder for year. The ISO 8601 formats are used by default in the java.time classes for parsing/generating strings.
Your input nearly complies. You could define a formatting pattern with a DateTimeFormatter object. But I would just prepend a -- onto the input.
String input = "02-29" ;
String inputModified = "--" + input ;
And then parse by default.
MonthDay md = MonthDay.parse( inputModified ) ;
See this code run live at IdeOne.com.
md.toString(): --02-29
Leap year
Note that your leap year problem goes away. By use an appropriate type that truly represents a month-and-day instead of a moment, we need not worry about leap year.
To get a date for this month-day, simply call MonthDay::atYear to obtain a LocalDate object. Pass a year number.
LocalDate leapYear2012 = md.atYear( 2012 ) ;
leapYear2012.toString(): 2012-02-29
Current year
Getting a date in the current year has a twist that may be surprising to you. Note that getting the current year requires getting the current date. And getting the current date requires a 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.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If you want to use the JVM’s current default time zone, make your intention clear by calling ZoneId.systemDefault(). If critical, confirm the zone with your user.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
In our case, we care only about the year. So we can use the Year class rather than LocalDate. But same idea with the time zone. If the current moment happens to be around New Years Eve/Day cutover, the year will vary around the globe by time zone.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
Year y = Year.now( z ) ;
LocalDate currentYear = md.atYear( y.getValue() ) ;
currentYear.toString(): 2019-02-28
Notice in the result above that leap year is handled automatically. There is no February 29th in 2019, so java.time adjusted to the 28th.
Parse as LocalDate
Alternatively, you could parse directly into a LocalDate. You would need to use the DateTimeFormatterBuilder class to build a DateTimeFormatter that defaults to a certain year.
Something like this:
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
long yearNumber = Year.now( zKolkata ).getValue() ;
DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.YEAR , yearNumber ).appendPattern( "MM-dd").toFormatter() ;
LocalDate ld = LocalDate.parse( "02-28" , formatter ) ;
System.out.println( "ld.toString(): " + ld ) ;
But I do not recommend this. The approach with MonthDay object is much more clear as to your problem, solution, and intention. Another benefit: if you are getting such inputs, I suspect you will likely need to be working with the month-day as such, and with MonthDay class you have an object at hand to do the job.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
This could be considered a little hacky, but you could always just tack the year onto the end of the date string before parsing, like this:
ds += "-" + Calendar.getInstance().get(Calendar.YEAR);
SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
// Parse date as usual
Get the year from the calendar as you do in the code, set the parse format string to MM-dd-yyyy and then do
Date d = df.parse(ds + "-" + year);
If you know your Strings are in the correct format, the other answers about appending the current year should suffice.
If your need is to handle input strings of unknown formats (you are unsure if the year is on the String or not), you can first attempt to parse the Date using the full format, then fall back on the shorter format with an override for the year.
public static Date parseDate(String ds) throws ParseException {
SimpleDateFormat fullFormat = new SimpleDateFormat("MM-dd-yyyy");
fullFormat.setLenient(false);
try {
return fullFormat.parse(ds);
} catch (ParseException e) {}
// Full format unsuccessful. Attempt short format.
SimpleDateFormat shortFormat = new SimpleDateFormat("MM-dd");
shortFormat.setLenient(false);
Date d = shortFormat.parse(ds);
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
cal.setTime(d);
cal.set(Calendar.YEAR, year);
return cal.getTime();
}
Bonus: If you want a "catch-all" parser for some reason, define a bunch of non-lenient date formats and check them one by one. Note that order matters; the first to match will return. If you want to set the default year, you'll have to take it a step further and check if the default 1970 year is somehow referred in the input:
public static Date parseDate(String ds) throws ParseException {
Calendar cal = Calendar.getInstance();
int currentYear = cal.get(Calendar.YEAR);
for (DateFormat knownFormat : knownFormats) {
try {
Date d = knownFormat.parse(ds);
cal.setTime(d);
if (cal.get(Calendar.YEAR) == 1970 && !ds.contains("70")) {
cal.set(Calendar.YEAR, currentYear);
}
return cal.getTime();
} catch (ParseException e) {}
}
throw new ParseException("Unknown date format for String: " + ds);
}
Related
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.
Please read question carefully before marking duplicate.
I want previous date of a corresponding date.(Not yesterday's date)
e.g. If user click button once he will be navigated to another screen and is shown data regarding yesterday.
And if he clicks again the same button on that screen, then data should be shown on day before yesterday....and so on... till data present in my database.
So I want to get previous date of a corresponding date. i.e. if I have date 31 Jan 2014(I'm using format 31012014 to store in db) then i should get date 30012014.
I know how to get yesterday's date e.g. below code
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -1);
DateFormat dateFormat = new SimpleDateFormat("ddMMyyyy", Locale.getDefault());
String yesterdayAsString = dateFormat.format(calendar.getTime());
which gives dates compared to today but I want previous date compared to some other valid date.
So how to get that.
You have to use SimpleDateFormat to convert String > Date, after Date > Calendar, for instance;
String sDate = "31012014";
SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyyyy", Locale.getDefault());
Date date = dateFormat.parse(sDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, -1);
String yesterdayAsString = dateFormat.format(calendar.getTime());
Use this, Its working and tested code.
private String getPreviousDate(String inputDate){
inputDate = "15-12-2015"; // for example
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
try {
Date date = format.parse(inputDate);
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -1);
inputDate = format.format(c.getTime());
Log.d("asd", "selected date : "+inputDate);
System.out.println(date);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
inputDate ="";
}
return inputDate;
}
tl;dr
Use modern java.time classes. Repeatedly subtract a day to move backwards in time.
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.now( // Determine the current date as perceived in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Europe/Paris" ) // Use real time zone names in `Continent/Region` format, never 2-4 letter pseudo-zones such as PST, EST, IST, CEST, etc.
) // Returns a `LocalDate` object.
.minusDays( 1 ) // Move back in time by one day, for yesterday’s date. Returns another separate `LocalDate` object rather than modify the original, per Immutable Objects pattern.
.minusDays( 1 ) // Continue moving back in time another day.
.minus(
Period.ofDays( 1 ) // Define a span-of-time as any number of years-months-weeks-days.
) // Continuing to subtract yet another day.
.toString() // Generate text representing that last generated `LocalDate` date-value using standard ISO 8601 format.
When parsing your text inputs.
LocalDate
.parse(
"30012014" ,
DateTimeFormatter.ofPattern( "ddMMuuuu" )
)
.minusDay( 1 )
.minus(
Period.ofDays( 1 )
)
java.time
The modern approach uses the java.time classes that years ago supplanted the troublesome old date-time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
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 during runtime(!), 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 2-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 ) ;
Date math
Your Question is not clear, but it seems you simply want to increment backwards in time one day at a time. This is quite easy with the LocalDate class offering plus & minus methods.
Call the convenience method, LocalDate::minusDays.
LocalDate yesterday = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).minusDays( 1 ) ;
To move backwards, subtract again.
LocalDate localDatePrior = yesterday.minusDays( 1 ) ;
And continue onwards.
localDatePrior = localDatePrior.minusDays( 1 ) ;
You can soft-code the period of time to subtract using the Period class with the LocalDate.minus method.
Period p = Period.ofDays( 1 ) ;
LocalDate localDatePrior = yesterday.minus( p ) ;
Database
(I'm using format 31012014 to store in db)
Don’t.
To store a date-only value in your database, use a date-only type in your column. In a SQL-compliant database, the type will be DATE for a date-only value.
As of JDBC 4.2 we can directly exchange java.time objects with the database.
myPreparedStatement.setObject( … , localDate ) ;
Retrieval.
LocalDate localDate = myResultSet.getObject( … , LocalDate.class ) ;
Parsing
But to directly address your current situation, you can parse your string with its peculiar format of DDMMYYYY.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMuuuu" ) ;
LocalDate localDate = LocalDate.parse( "30012014" , f ) ;
String output = localDate.toString() ; // Generate text in standard ISO 8601 format.
By the way, rather than invent your own date-time format, always use standard ISO 8601 formats when exchanging date-time values as text. The java.time classes wisely use these formats by default when parsing/generating strings.
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….
Try this one
String prevDate;
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
String todayDate=df.format(c);
Date date = null;
try {
date = df.parse(todayDate);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, -1);
prevDate = df.format(calendar.getTime());
Test=(TextView)findViewById(R.id.test);
Test.setText(prevDate);
You've got everything right, except before you "add" -1 days, you need to set it to the date you want (before finding the previous date previous):
Calendar calendar = Calendar.getInstance();
calendar.set(2014, Calendar.JUNE, 9);
calendar.add(Calendar.DATE, -1);
...
First off just as a tip, it is better to store your dates as timestamps like so you won't be dependent on time formats.
As for your question, just keep your current date in a variable and send it to your method once the button is clicked and then subtract an extra day
Calendar curDate = Calendar.getInstance();
curDate.add(Calendar.DATE, -1);
and use your curDate variable from then on
Try this:
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -1);
String yesterdayAsString = fmtOut.format(calendar.getTime());
long calendar=Calendar.getInstance().getTimeInMillis()-1000*60*60*24;
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy");
String date = sdf.format(calendar);
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 in need to manipulate on java.sql.Timestamp.
Input to the function is:
Formatted DateTime in java.sql.Timestamp
[Possible date formats are: MM/dd/yyyy hh:mm:ss aa, MM/dd/yyyy hh:mm:ss, MM/dd/yyyy hh:mm aa, MM/dd/yyyy HH:mm, MM/dd/yy hh:mm aa, MM/dd/yy HH:mm, MM/dd/yyyy, and some others]
Required Output:
java.sql.Timestamp in another Timezone the same formatted DateTime as input
So basically I need to change timezone of the DateTime in java.sql.Timestamp
I have seen other posts, which mention to use JODA, but I can't use it due to some restrictions.
I have tried
- to convert java.sql.Timestamp to java.date.Calendar,
- then change the timezone,
- then convert to it to date
- format date to the same formatted datetime
See the code below:
Timestamp ts = "2012-06-20 18:22:42.0"; // I get this type of value from another function
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
cal.add(Calendar.HOUR, -8);
String string = cal.getTime().toString(); // return value is in " DAY MMM dd hh:mm:ss PDT yyyy " format i.e. Wed Jun 20 10:22:42 PDT 2012
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); // This could be any format required
Date date;
try {
date = formatter.parse(string); // I am getting exception here on parsing
} catch (ParseException e1) {
e1.printStackTrace();
}
Can anyone tell me what is wrong here, or is there any other way to manipulate on Timezone for java.sql.Timestamp ?
Thanks.
You are misunderstanding and abusing these classes.
Timestamp & Date have no time zone but UTC
manipulate on Timezone for java.sql.Timestamp
A java.sql.Timestamp is always a moment in UTC. No other time zone is involved, only UTC. Ditto for java.util.Date – always in UTC, no other time zone involved.
So your Question, as quoted above, does not make sense.
Timestamp & Date have no “format”
Neither Timestamp nor Date have a “format”. They use their own internally defined way to track the date-time. They are not strings, so they have no format. You can generate a String to represent their value in a particular format, but such a String is distinct and separate from the generating object.
java.time
You are using troublesome old date-time classes that wore supplanted years ago by the java.time classes.
Both Timestamp and Date are replaced by 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).
Your input is
String input = "2012-06-20 18:22:42.0" ;
That input is nearly compliant with standard ISO 8601 format. To comply fully, replace the SPACE in the middle with a T.
String input = "2012-06-20 18:22:42.0".replace( " " , "T" ) ;
Parse as a LocalDateTime because it lacks an indicator of offset-from-UTC or time zone.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
A LocalDateTime, like your input string, does not represent a moment, is not a point on the timeline. Without the context of a time zone or offset-from-UTC, it has no real meaning. It represents only potential moments along a range of about 26-27 hours.
If you know the intended time zone, apply it to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
As for the other formats you mentioned, your Question is not at all clear. Search Stack Overflow for DateTimeFormatter class to see many examples and discussions of generating/parsing strings with the java.time classes. But first, get clear on the crucial concept that strings are not the date-time objects, and the date-time objects are not strings.
Database
If you were using java.sql.Timestamp to exchange data with a database, no need for that class anymore. As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
myPreparedStatement.setObject( … , instant ) ;
…and…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
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.
Think of Timestamp as being a fixed point in time, disconnected from where on earth you happen to be looking at a clock.
If you want to display what's on the calendar/clock for a person at that instant in a particular time zone, you can set a calendar to that time zone and then associate your SimpleDateFormat to that calendar.
For example:
public void testFormat() throws Exception {
Calendar pacific = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Calendar atlantic = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Timestamp ts = new Timestamp(System.currentTimeMillis());
sdf.setCalendar(pacific);
System.out.println(sdf.format(ts));
sdf.setCalendar(atlantic);
System.out.println(sdf.format(ts));
}
My output was:
2012-06-25 20:27:12.506
2012-06-25 23:27:12.506
I got it solved, I am putting code for reference.
Timestamp ts = "2012-06-20 18:22:42.0"; // input date in Timestamp format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar cal = Calendar.getInstance();
cal.setTime(ts)
cal.add(Calendar.HOUR,-7); // Time different between UTC and PDT is -7 hours
String convertedCal = dateFormat.format(cal.getTime()); // This String is converted datetime
/* Now convert String formatted DateTime to Timestamp*/
SimpleDateFormat formatFrom = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
Date date = formatFrom.parse(convertedCal);
Timestamp finalTS = new Timestamp(date.getTime()); // Final value in Timestamp: 2012-06-20 11:22:42.0
} catch (Exception e) {
e.printStackTrace();
}
Couldn't you simply:
Get original time in milliseconds
Convert timezone difference to milliseconds
Add or subtract the difference from the original time.
Create a new timestamp using the new time in milliseconds
you miss one argumment in formatter.parse
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition)
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