I am trying to correct a date with some offset value according to the time zone. So, when I format a timestamp with a time zone offset, I expected that SimpleDateFormat will add the offset value to the time.
Here is what I tried:
package com.krishna.mytrials;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DateExperiments {
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//Date we set in UI
Date today = new Date();
//The long value
String todayBrowserLocalTimeStamp = sdf.format(today);
System.out.println(todayBrowserLocalTimeStamp);
Date todayBrowserLocalTimeStampDate = sdf.parse(todayBrowserLocalTimeStamp);
System.out.println("Today's browser local time stamp: " + todayBrowserLocalTimeStampDate);
System.out.println("And its long value:" + todayBrowserLocalTimeStampDate.getTime());
System.out.println("Date generate from long:"+ new Date(todayBrowserLocalTimeStampDate.getTime()));
//What server does to the above mid night time stamp of browser-local time zone
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
//What we get after it applied the server time zone to browser-local date
//### This is the wrong date
SimpleDateFormat sdf2 = new SimpleDateFormat();
sdf2.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf2.applyPattern("yyyy-MM-dd HH:mm");
System.out.println(sdf2.format(todayBrowserLocalTimeStampDate));
String utcDateString = sdf.format(todayBrowserLocalTimeStampDate);
System.out.println("The above mid night time stamp of browser-local time zone"
+ "is converted to GMT.### The wrong one:");
System.out.println(utcDateString);
//### The wrong date constructed
Date utcDate = sdf.parse(utcDateString);
System.out.println("###Wrong date:"+utcDate);
//### The wrong long
Long utcLong = utcDate.getTime();
System.out.println("###Wrong long:"+utcLong);
// What we will do with the GMT+05:30
sdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
String dateToBeCorrected = sdf2.format(todayBrowserLocalTimeStampDate);
System.out.println("Date to be corrected:"+ dateToBeCorrected);
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date correctedDate = sdf3.parse(dateToBeCorrected);
System.out.println(correctedDate);
SimpleDateFormat sdf4 = new SimpleDateFormat();
sdf4.setTimeZone(TimeZone.getTimeZone("IST"));
String correctedString = sdf4.format(correctedDate);
System.out.println("Corrected date:" + formatDateToString(correctedDate,"dd MMM yyyy hh:mm:ss a", "IST"));
}
public static String formatDateToString(Date date, String format,
String timeZone) {
// null check
if (date == null) return null;
// create SimpleDateFormat object with input format
SimpleDateFormat sdf = new SimpleDateFormat(format);
// default system timezone if passed null or empty
if (timeZone == null || "".equalsIgnoreCase(timeZone.trim())) {
timeZone = Calendar.getInstance().getTimeZone().getID();
}
// set timezone to SimpleDateFormat
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
// return Date in required format with timezone as String
return sdf.format(date);
}
}
Here is the output:
2017-01-12
Today's browser local time stamp: Thu Jan 12 00:00:00 IST 2017
And its long value:1484159400000
Date generate from long:Thu Jan 12 00:00:00 IST 2017
2017-01-11 18:30
The above mid night time stamp of browser-local time zoneis converted to GMT.### The wrong one:
2017-01-11
###Wrong date:Wed Jan 11 05:30:00 IST 2017
###Wrong long:1484092800000
Date to be corrected:2017-01-11 18:30
Wed Jan 11 18:30:00 IST 2017
Corrected date:11 Jan 2017 06:30:00 PM
It is supposed add 05:30. to the date. What am I doing wrong?
You have to consider that roundtrips using formatting and parsing can loose informations. This is due to the fact that a formatted date might contain less informations than the original Date-instance had. Look at this data loss:
Original timestamp (variable todayBrowserLocalTimeStampDate) was: 2017-01-11 18:30 (in UTC) or as long: 1484175600000L
String utcDateString = sdf.format(new Date(1484175600000L));
// 2017-01-11
Date utcDate = sdf.parse(utcDateString);
Here you strip away the time part AND parse the stripped string again. Of course, the resulting new Date-instance must loose the corresponding time part, too, and cannot be the same as before.
2017-01-11 (with zero time) would be rendered in your IST-zone 5:30 hours later, that is: 2017-01-11T05:30+05:30 (remember: Date.toString() uses your IST-zone assuming that is your system zone). This is same instant as 2017-01-11T00:00Z. All is fine, only your expectation expressed in line indicated by prefix ###Wrong date is wrong.
I am working on a date picker where there is a range of dates. I noticed that all of my dates are a day behind and while investigating the issue I narrowed down the problem to the SimpleDateFormat object. No matter what Unix time I give it it sets the date to the previous day. An example of this behaviour is
String myFormat = "MM/dd/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(myFormat);
Log.d(TAG, "Time Zone: " + cal.getTimeZone().getDisplayName());
Log.d(TAG, "Printable: " + sdf.format(0));
The output that I see in the logger is
Time Zone: UTC
Printable: 12/31/1969
Why does the formatter use December 31 instead of January 1st 1970?
Because the DateFormat also has a TimeZone (and your system isn't set to UTC). You can change it with DateFormat.setTimeZone(TimeZone). Something like
String myFormat = "MM/dd/yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(myFormat);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Printable: " + sdf.format(0));
Output is (as you expected)
Printable: 01/01/1970
I am converting timestamp to date format yyyy-MM-dd HH:mm:ss.SSS and I am using America/New_York as TimeZone. Whenever I convert the timestamp into the date it shows one hour less than usual date and time. How to resolve this in java?
Here's the code:
String timestamp = "1431941838000";
long time = Long.valueOf(timestamp);
Date currentDate = new Date(time);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
TimeZone zone = TimeZone.getTimeZone("America/New_York");
df.setTimeZone(zone);
String finale = df.format(currentDate);
Try to using EST to replace America/New_York like
TimeZone zone = TimeZone.getTimeZone("EST");
Updated
It's My Test code:
String timestamp = "1431941838000";
long time = Long.valueOf(timestamp);
Date currentDate = new Date(time);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
TimeZone zoneNewYork = TimeZone.getTimeZone("America/New_York");
df.setTimeZone(zoneNewYork);
String finale = df.format(currentDate);
System.out.println(finale);
TimeZone zoneEst = TimeZone.getTimeZone("EST");
df.setTimeZone(zoneEst);
finale = df.format(currentDate);
System.out.println(finale);
And My result as bellow:
2015-05-18 05:37:18.000
2015-05-18 04:37:18.000
You have an extra point in this line:
TimeZone zone = TimeZone.getTimeZone("America/New_York").;
// ^ here!!!
UPDATE if you dont get any error, the output must be the correct:
EST is UTC - 5 hours. America/New_York is EST in the winter and E*D*T in the summer, so check if String timestamp = "1431941838000"; is winter or summer...
This code works ok:
Calendar calNewYork = Calendar.getInstance();
calNewYork.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("Time in New York: " + calNewYork.get(Calendar.HOUR_OF_DAY) + ":"
+ calNewYork.get(Calendar.MINUTE));
Use this to check your time:
long timestamp = "1431941838000";
Calendar calNewYork = Calendar.getInstance();
calNewYork.setTimeZone(TimeZone.getTimeZone("America/New_York"));
calNewYork.setTime(new Date(timestamp));
System.out.println("Time in New York: " + calNewYork.get(Calendar.HOUR_OF_DAY) + ":"
+ calNewYork.get(Calendar.MINUTE));
How to convert calendar date to yyyy-MM-dd format.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
Date date = cal.getTime();
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
String date1 = format1.format(date);
Date inActiveDate = null;
try {
inActiveDate = format1.parse(date1);
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
This will produce inActiveDate = Wed Sep 26 00:00:00 IST 2012. But what I need is 2012-09-26. My purpose is to compare this date with another date in my database using Hibernate criteria. So I need the date object in yyyy-MM-dd format.
A Java Date is a container for the number of milliseconds since January 1, 1970, 00:00:00 GMT.
When you use something like System.out.println(date), Java uses Date.toString() to print the contents.
The only way to change it is to override Date and provide your own implementation of Date.toString(). Now before you fire up your IDE and try this, I wouldn't; it will only complicate matters. You are better off formatting the date to the format you want to use (or display).
Java 8+
LocalDateTime ldt = LocalDateTime.now().plusDays(1);
DateTimeFormatter formmat1 = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
System.out.println(ldt);
// Output "2018-05-12T17:21:53.658"
String formatter = formmat1.format(ldt);
System.out.println(formatter);
// 2018-05-12
Prior to Java 8
You should be making use of the ThreeTen Backport
The following is maintained for historical purposes (as the original answer)
What you can do, is format the date.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(cal.getTime());
// Output "Wed Sep 26 14:23:28 EST 2012"
String formatted = format1.format(cal.getTime());
System.out.println(formatted);
// Output "2012-09-26"
System.out.println(format1.parse(formatted));
// Output "Wed Sep 26 00:00:00 EST 2012"
These are actually the same date, represented differently.
Your code is wrong. No point of parsing date and keep that as Date object.
You can format the calender date object when you want to display and keep that as a string.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
Date date = cal.getTime();
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
String inActiveDate = null;
try {
inActiveDate = format1.format(date);
System.out.println(inActiveDate );
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
java.time
The answer by MadProgrammer is correct, especially the tip about Joda-Time. The successor to Joda-Time is now built into Java 8 as the new java.time package. Here's example code in Java 8.
When working with date-time (as opposed to local date), the time zone in critical. The day-of-month depends on the time zone. For example, the India time zone is +05:30 (five and a half hours ahead of UTC), while France is only one hour ahead. So a moment in a new day in India has one date while the same moment in France has “yesterday’s” date. Creating string output lacking any time zone or offset information is creating ambiguity. You asked for YYYY-MM-DD output so I provided, but I don't recommend it. Instead of ISO_LOCAL_DATE I would have used ISO_DATE to get this output: 2014-02-25+05:30
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zonedDateTime = ZonedDateTime.now( zoneId );
DateTimeFormatter formatterOutput = DateTimeFormatter.ISO_LOCAL_DATE; // Caution: The "LOCAL" part means we are losing time zone information, creating ambiguity.
String output = formatterOutput.format( zonedDateTime );
Dump to console…
System.out.println( "zonedDateTime: " + zonedDateTime );
System.out.println( "output: " + output );
When run…
zonedDateTime: 2014-02-25T14:22:20.919+05:30[Asia/Kolkata]
output: 2014-02-25
Joda-Time
Similar code using the Joda-Time library, the precursor to java.time.
DateTimeZone zone = new DateTimeZone( "Asia/Kolkata" );
DateTime dateTime = DateTime.now( zone );
DateTimeFormatter formatter = ISODateTimeFormat.date();
String output = formatter.print( dateTime );
ISO 8601
By the way, that format of your input string is a standard format, one of several handy date-time string formats defined by ISO 8601.
Both Joda-Time and java.time use ISO 8601 formats by default when parsing and generating string representations of various date-time values.
java.util.Date object can't represent date in custom format instead you've to use SimpleDateFormat.format method that returns string.
String myString=format1.format(date);
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(year, month, date);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy MM dd");
String formatted = format1.format(cal.getTime());
System.out.println(formatted);
}
In order to parse a java.util.Date object you have to convert it to String first using your own format.
inActiveDate = format1.parse( format1.format(date) );
But I believe you are being redundant here.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 7);
Date date = c.getTime();
SimpleDateFormat ft = new SimpleDateFormat("MM-dd-YYYY");
JOptionPane.showMessageDialog(null, ft.format(date));
This will display your date + 7 days in month, day and year format in a JOption window pane.
public static String ThisWeekStartDate(WebDriver driver) {
Calendar c = Calendar.getInstance();
//ensure the method works within current month
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println("Before Start Date " + c.getTime());
Date date = c.getTime();
SimpleDateFormat dfDate = new SimpleDateFormat("dd MMM yyyy hh.mm a");
String CurrentDate = dfDate.format(date);
System.out.println("Start Date " + CurrentDate);
return CurrentDate;
}
public static String ThisWeekEndDate(WebDriver driver) {
Calendar c = Calendar.getInstance();
//ensure the method works within current month
c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
System.out.println("Before End Date " + c.getTime());
Date date = c.getTime();
SimpleDateFormat dfDate = new SimpleDateFormat("dd MMM yyyy hh.mm a");
String CurrentDate = dfDate.format(date);
System.out.println("End Date " + CurrentDate);
return CurrentDate;
}
I found this code where date is compared in a format to compare with date field in database...may be this might be helpful to you...
When you convert the string to date using simpledateformat, it is hard to compare with the Date field in mysql databases.
So convert the java string date in the format using select STR_to_DATE('yourdate','%m/%d/%Y') --> in this format, then you will get the exact date format of mysql date field.
http://javainfinite.com/java/java-convert-string-to-date-and-compare/
My answer is for kotlin language.
You can use SimpleDateFormat to achieve the result:
val date = Date(timeInSec)
val formattedDate = SimpleDateFormat("yyyy-MM-dd", Locale("IN")).format(date)
for details click here.
OR
Use Calendar to do it for you:
val dateObject = Date(timeInMillis)
val calendarInstance = Calendar.getInstance()
calendarInstance.time = dateObject
val date = "${calendarInstance.get(Calendar.YEAR)}-${calendarInstance.get(Calendar.MONTH)}-${calendarInstance.get(Calendar.DATE)}"
For more details check this answer.
I don't know about y'all, but I always want this stuff as a one-liner. The other answers are fine and dandy and work great, but here is it condensed to a single line. Now you can hold less lines of code in your mind :-).
Here is the one Liner:
String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
I want to get the current date converted to America/Montreal timezone. I'm doing it like this:
Date date = new Date();
TimeZone timeZone = TimeZone.getTimeZone ("America/Montreal");
Calendar cal = new GregorianCalendar(timeZone);
cal.setTime(date);
String whatIWant = "" + cal.get(Calendar.HOUR_OF_DAY) + ':'+
cal.get(Calendar.MINUTE)+ ':'+ cal.get(Calendar.SECOND);
log.info(whatIWant);
The conversion is just fine but I was wondering how robust this code is. What will happen when in no daylight saving?
That code is fine. Java automatically takes winter time or summer time into account.
You could also do this by using a DateFormat object to convert the date to a string, setting the desired time zone on the DateFormat object:
Date date = new Date();
DateFormat df = new SimpleDateFormat("HH:mm:ss");
// Tell the DateFormat that you want the time in this timezone
df.setTimeZone(TimeZone.getTimeZone("America/Montreal"));
String whatIWant = df.format(date);