I have a date-time in IST. I want to convert it to US timezones based on input considering the daylight saving time,
if there is daylight saving time for the given date-time in java.
This is what i tried
function convert(Date dt,int toTimeZoneId){
Calendar cal = Calendar.getInstance();
cal.setTime(dt); // Geting time in IST
//Converted to GMT and set in cal
switch(toTimeZoneId){
case 1: tzTarget = TimeZone.getTimeZone("America/Adak");
offset = -10;
break;
case 2: tzTarget = TimeZone.getTimeZone("America/Anchorage");
offset = -9;
break;
case 3: tzTarget = TimeZone.getTimeZone("America/Los_Angeles");
offset = -8;
break;
case 4: tzTarget = TimeZone.getTimeZone("America/Denver");
offset = -7;
break;
case 5: tzTarget = TimeZone.getTimeZone("America/Chicago");
offset = -6;
break;
case 6: tzTarget = TimeZone.getTimeZone("America/New_York");
offset = -5;
break;
}
//converting from GMT to US timezones based on offset and dst
cal.setTimeZone(tzTarget);
dst = tzTarget.getDSTSavings();
dst = dst/3600000;
offset = offset + dst;
cal.add(Calendar.HOUR, offset);
Date date = cal.getTime();
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
}
To just convert a given date to different time zones, you need to create the date formatter with appropriate time zone. A date instance is just a long value relative to epoch; it doesn't have time zone information. So we aren't converting it to a different time zone, we are just representing it in different time zones. That is why we need time zone information when we want to create a string representation of the date instance.
Here's some code to illustrate the above. I've just added the time zone to your date format string to make things clear.
/*
* Converts a specified time to different time zones
*/
public void convert(Date dt) {
// This prints: Date with default formatter: 2013-03-14 22:00:12 PDT
// As my machine is in PDT time zone
System.out.println("Date with default formatter: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(dt));
// This prints: Date with IST time zone formatter: 2013-03-15 10:30:12 GMT+05:30
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
TimeZone tz = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz);
String dateIST = sdf.format(dt);
System.out.println("Date with IST time zone formatter: " + dateIST);
// This prints: Date CST time zone formatter: 2013-03-15 00:00:12 CDT
tz = TimeZone.getTimeZone("CST");
sdf.setTimeZone(tz);
System.out.println("Date CST time zone formatter: " + sdf.format(dt));
}
I think this is what you are trying to do - convert a given time to different time zones. To do that I don't think you need to add/subtract any offset, as you just want the same time represented in a different time zone and the TimeZone instance should be able to take care of that during formatting.
As for daylight saving, the TimeZone should be able to take care of that as well. If you notice in my example code, I've used CST to create TimeZone instance and CST is "GMT -06 hours". But the output it gives is in CDT, which is "GMT -05 hours", because this time zone instance uses daylight saving. So by using the appropriate time zone you should be able to handle daylight saving as well.
java.util.GregorianCalendar allows you create dates with timezones. Unfortunately, addition and subtraction suck from there. (How do you subtract Dates in Java?)
Since you're converting between two timezones, you can also make use of java.util.TimeZone and use the difference of tz1.getOffset(date) - tz2.getOffset(date). Mind the ordering when doing subtraction.
Joda-Time
Using Joda-Time makes this much easier. Or try the new java.time package in Java 8.
Here is some example code using Joda-Time 2.3. Search StackOverflow for many more examples.
India time…
DateTimeZone timeZone_India = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( date, timeZone_India );
Adjusting the same moment for display as New York time…
DateTimeZone timeZone_NewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = dateTimeIndia.withZone( timeZone_NewYork ); // Same moment, different wall-clock time.
Still the same moment, but in UTC (no time zone offset).
DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC );
Use Proper Time Zone Names
Avoid using 3-4 letter time zone codes. They are neither standardized nor unique. Your IST for example can mean either Irish Standard Time or India Standard Time. Use proper time zone names.
Related
I am trying to get time (HH:MM) from below code in IST format but it still display UTC date, time.
Please help.
public static void main (String args[]) throws ParseException {
String date = "2021-07-05T14:17:00.000Z";
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
String timezoneID = timeZone.getID();
// Convert to System format from UTC
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date actualDate = format1.parse(date);
format1.setTimeZone(TimeZone.getTimeZone(timezoneID));
String date1 = format1.format(actualDate);
String time = date1.substring(11, 16);
String timezoneValue = TimeZone.getTimeZone(timezoneID).getDisplayName(false, TimeZone.SHORT);
String finalTime = time + " " + timezoneValue;
System.out.print(finalTime);
}
java.time
I strongly recommend that you use java.time, the modern Java date and time API, for your date and time work. Then your task becomes pretty simple. Rather than a formatter for your input format I want to define a formatter for your desired time format:
private static final DateTimeFormatter TIME_FORMATTER
= DateTimeFormatter.ofPattern("HH:mm zzz", Locale.ENGLISH);
Now the operation goes in these few lines:
String date = "2021-07-05T14:17:00.000Z";
String finalTime = Instant.parse(date)
.atZone(ZoneId.systemDefault())
.format(TIME_FORMATTER);
System.out.println(finalTime);
Output when I ran in Europe/Dublin time zone:
15:17 IST
Here IST is for Irish Summer Time. IST has several meanings, and I wasn’t sure which one you intended. Also many of the other popular time zone abbreviations are ambiguous. IST may also mean Israel Standard Time, but not here, since Israel uses Israel Daylight Time or IDT at this time of year. One other interpretation is India Standard Time used in India and Sri Lanka, So let’s try running the code in Asia/Kolkata time zone.
19:47 IST
I am exploiting the fact that your string is in ISO 8601 format, the format that the classes of java.time parse and also print as their default, that is, without any specified formatter.
What went wrong in your code?
Your bug is here:
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
You must never hardcode Z as a literal in your format pattern, which is what you are doing when enclosing it in single quotes. The Z is a UTC offset and needs to be parsed as such so that Java knows that your date and time are in UTC (which is what Z means). When you hardcode the Z, SimpleDateFormat understands the date and time to be in the default time zone of the JVM. So when afterward you try to convert into that time zone, the time of day is not changed. You’re converting into the time zone you already had. It’s a no-op.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Time Zone Abbreviations – Worldwide List
You are parsing the date using your default TimeZone, not UTC.
You never called format1.setTimeZone before parsing. A DateFormat uses the default timezone unless you set it to something else.
Let’s look at each line of your code:
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
That is getting the default TimeZone. You don’t need a Calendar object for that; just call TimeZone.getDefault().
String timezoneID = timeZone.getID();
There is no reason to call that. You already have a TimeZone object. Converting it to a string ID and back to a TimeZone is a pointless round-trip operation. So, you should remove all uses of timezoneID.
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
That is the problem. The DateFormat doesn’t treat the 'Z' as anything special; it’s just a literal character which the DateFormat knows not to parse.
You need to actually tell the DateFormat that it’s parsing a UTC time:
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
TimeZone utc = TimeZone.getTimeZone(ZoneOffset.UTC);
format1.setTimeZone(utc);
Date actualDate = format1.parse(date);
Instead of cutting out pieces of a formatted string, make a new DateFormat that does exactly what you want:
DateFormat timeFormat = new SimpleDateFormat("HH:mm z");
String finalTime = timeFormat.format(actualDate);
Since a SimpleDateFormat always uses the default TimeZone when it is created, there is no need to call this format object’s setTimeZone method.
I should mention that the java.time and java.time.format packages are much better for working with dates and times:
String date = "2021-07-05T14:17:00.000Z";
Instant instant = Instant.parse(date);
ZonedDateTime utcDateTime = instant.atZone(ZoneOffset.UTC);
ZonedDateTime istDateTime =
utcDateTime.withZoneSameInstant(ZoneId.systemDefault());
String finalTime = String.format("%tR %<tZ", istDateTime);
// Or:
// String finalTime = istDateTime.toLocalTime() + " "
// + itsDateTime.getZone().getDisplayName(
// TextStyle.SHORT, Locale.getDefault());
format1.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
is what you need since the 3-letter zone names are really deprecated. Plus:
String timezoneValue = format1.getTimeZone().getDisplayName(false, TimeZone.SHORT);
The method Calendar.getInstance() gets a calendar using the default time zone and locale - UTC±00:00.
Use "IST" instead of timeZone.getID().
Exemple:
String date="2021-07-05T14:17:00.000Z";
Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
String timezoneID = "IST"; // <<<<<
// Convert to System format from UTC
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date actualDate = format1.parse(date);
format1.setTimeZone(TimeZone.getTimeZone(timezoneID));
String date1 = format1.format(actualDate);
String time = date1.substring(11, 16);
String timezoneValue = TimeZone.getTimeZone(timezoneID).getDisplayName(false, TimeZone.SHORT);
String finalTime = time + " " + timezoneValue;
System.out.print(finalTime);
This Java code, given a date as a string, is supposed to print the epoch timestamp for the same date at the midnight for the CET zone (supposing I'm not in the same zone).
public static void main(String[] args) throws ParseException {
String dateStr = "1995-06-06";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
Date date = formatter.parse(dateStr);
Calendar c = new GregorianCalendar();
c.setTimeZone(TimeZone.getTimeZone("CET"));
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
System.out.println("Epoch timestamp = " + c.getTime().getTime());
}
If I run the above program I should get printed:
Epoch timestamp = 802389600000
And I can verify it's correct here:
https://www.epochconverter.com/timezones?q=802389600&tz=Europe%2FMalta
Now, that works for most of the dates. However, there are some bizarre dates like "1975-09-19", where it doesn't work. In fact, It generates 180313200000 as a timestamp, which gives 1am and not midnight:
https://www.epochconverter.com/timezones?q=180313200&tz=Europe%2FMalta
Can you explain why? What am I missing?
Time zone discrepancy
Your Java code uses CET, which is not really a time zone (for example because most of the areas where it’s used use CEST instead for most of the year). Java translates CET to Europe/Paris. France and Paris did not use summer time (DST) in 1975. It was reintroduced in March 1976.
Your link to the epoch converter specifies Malta time zone (Europe/Malta). Malta did use summer time in 1975: it was on CEST from 20 April to 21 September that year.
This explains the difference in your results.
In Java code
If you wanted Malta time:
String dateStr = "1975-09-19";
long epochTimestamp =
LocalDate
.parse(dateStr)
.atStartOfDay(ZoneId.of("Europe/Malta"))
.toInstant()
.toEpochMilli();
System.out.println("Epoch timestamp = " + epochTimestamp);
This prints:
Epoch timestamp = 180309600000
And the epoch converter that you linked to is happy to agree:
Conversion results (180309600)
180309600 converts to Friday September 19, 1975 00:00:00 (am) in
time zone Europe/Malta (CEST) The offset (difference to Greenwich
Time/GMT) is +02:00 or in seconds 7200. This date is in daylight
saving time.
In Java do use java.time, the modern Java date and time API, for your date and time work. It is so much nicer to work with compared to the old date and time classes like SimpleDateFormat, TimeZone, Date and Calendar. Also setting the hours, etc., to 0 is not the correct way to get the first moment of the day. There are cases where summer time begins at the start of the day, so the first moment of the day is 01:00:00. Java knows that, so the atStartOfDay method will give you the correct forst moment of the day in question.
And no matter if using outdated or modern classes always specify time zone in the region/city format, for example Europe/Paris or Europe/Malta. The three, four and five letter time zone abbreviations are often ambiguous and often not true time zones, so not to be relied on.
Links
Time Zone in Paris, Île-de-France, France
Time Zone in Valletta, Malta
Oracle tutorial: Date Time explaining how to use java.time.
There seems to be a difference concerning daylight saving time between your date examples.
If I use java.time (which should always be used since Java 8), I get results with different offsets:
"+02:00" for "1995-06-06" and
"+01:00" for "1975-09-19"
This is how I got the results:
public static void main(String[] args) {
// provide two sample dates
String workingDateStr = "1995-06-06";
String failingDateStr = "1975-09-19";
// and a formatter that parses the format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// then parse them to date objects that don't know about time or zone
LocalDate workingDate = LocalDate.parse(workingDateStr, dtf);
LocalDate failingDate = LocalDate.parse(failingDateStr, dtf);
/*
* then create an objects that are aware of time and zone
* by using the parsed dates, adding a time of 00:00:00 and a zone
*/
ZonedDateTime workingZdt = ZonedDateTime.of(workingDate, LocalTime.MIN, ZoneId.of("CET"));
ZonedDateTime failingZdt = ZonedDateTime.of(failingDate, LocalTime.MIN, ZoneId.of("CET"));
// finally, print different representations of the results
System.out.println(workingZdt + " ——> " + workingZdt.toInstant().toEpochMilli());
System.out.println(failingZdt + " ——> " + failingZdt.toInstant().toEpochMilli());
}
Output:
1995-06-06T00:00+02:00[CET] ——> 802389600000
1975-09-19T00:00+01:00[CET] ——> 180313200000
That means you might be better off using specific offsets instead of zones.
This issue could be due to the timing of the introduction of Daylight Saving Time in Malta, have a look at the following code and its output:
public static void main(String[] args) {
// provide two sample dates
String failingDateStr = "1975-09-19";
// and a formatter that parses the format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// then parse them to date objects that don't know about time or zone
LocalDate failingDate = LocalDate.parse(failingDateStr, dtf);
/*
* then create an objects that are aware of time and zone
* by using the parsed dates, adding a time of 00:00:00 and a zone
*/
ZonedDateTime failingZdt = ZonedDateTime.of(failingDate, LocalTime.MIN, ZoneId.of("CET"));
// add some years to 1975 and...
for (int year = 0; year < 4; year++) {
// ... print the different representations of the result
System.out.println(failingZdt.plusYears(year) + " ——> "
+ failingZdt.plusYears(year).toInstant().toEpochMilli());
}
}
Output:
1975-09-19T00:00+01:00[CET] ——> 180313200000
1976-09-19T00:00+01:00[CET] ——> 211935600000
1977-09-19T00:00+02:00[CET] ——> 243468000000
1978-09-19T00:00+02:00[CET] ——> 275004000000
This output indicates an introduction in 1977... Is that correct?
I have a date, for example Thu April 17 09:03:01 GMT 2014 in the timezone:
sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
and everytime a try to convert to UTC it returns Thu April 17 10:03:01 GMT 2014
This does not make sense because the corresponding UTC time is actually Thu April 17 08:03:01 GMT 2014 since that the in my timezone time is added 1hour due to daylight savings.
The code I use to convert is this:
//timeZone - id="Europe/London"
public static Date timeZoneConvertDate(Date date, TimeZone timeZone) {
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(timeZone);
sdf.applyPattern("dd-MM-yyyy HH:mm:ss");
String newDate = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date nd = sdf.parse(newDate);
return nd;
} catch (ParseException e) {
return null;
}
}
Could someone explain what I'm doing wrong?
tl;dr
A Date has no timezone associated with it, so you cannot create a method that adjusts the timezone of a date object. You need to work with Calendar objects if you want to retain TZ information or, preferably, take a look at Joda-Time.
Explanation of Your Output
A Date value has no timezone information; it's merely the number of milliseconds since the epoch. With that in mind, let's see what you're doing:
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(timeZone);
sdf.applyPattern("dd-MM-yyyy HH:mm:ss");
String newDate = sdf.format(date);
This part of your code creates a formatter that will print the date in the London timezone. So the result you'll get at the time of writing is approximately: 17-04-2014 11:38:15 (assuming you just created your date object).
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date nd = sdf.parse(newDate);
return nd;
} catch (ParseException e) {
return null;
}
Here you tell the date parser to read the date as though it were a UTC date. It uses that information to know how many milliseconds since the epoch have passed. The date object you get back still has no timezone associated with it.
UTC is an hour behind British Summer Time, so it will create a date object that appears an hour ahead when printed in the BST timezone. So when I print nd, I get: Thu Apr 17 12:38:15 BST 2014.
No Time Zone In java.util.Date
As the correct answer by Duncan said a java.util.Date has no time zone component. Confusingly its toString method applies the JVM's default time zone. To display in another time zone, use SimpleDateFormat to apply an adjustment.
Even better, avoid the notoriously troublesome java.util.Date, .Calendar, and SimpleDateFormat. Use either Joda-Time or the new java.time package in Java 8.
Joda-Time
In Joda-Time, a DateTime object truly does contain an assigned time zone. If you do not specify a time zone, the JVM's default time zone is assigned.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/London" );
DateTime dateTime = new DateTime( 2014, 4, 17, 9, 3, 1, timeZone );
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
When run…
dateTime: 2014-04-17T09:03:01.000+01:00
dateTimeUtc: 2014-04-17T08:03:01.000Z
dateTimeIndia: 2014-04-17T13:33:01.000+05:30 (note the half-hour difference, +05:30)
You can easily convert back and forth to java.util.Date.
DateTime dateTime = new DateTime( myJUDate, timeZone );
…and…
Java.util.Date date = dateTime.toDate();
I am trying to convert a formatted date String to Date object. Date String is formatted to some other timezone.
When I do sdf.parse(String) it returns me my System date object.
Code is as below,
static Date convertGMTTime(String timeZone, long longDate){
Date convertedTime = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
Date date = new Date(longDate);
System.out.println("timezone: "+timeZone +", timestamp: "+date);
Locale locale = Locale.ENGLISH;
TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
System.out.println("Source timezone: "+destTimeZone);
/* DateFormat formatter = DateFormat.getDateTimeInstance(
DateFormat.DEFAULT,
DateFormat.DEFAULT,
locale);
formatter.setTimeZone(destTimeZone);*/
sdf.setTimeZone(destTimeZone);
String convertedDateStr = sdf.format(date);
System.out.println("convertedDateStr: "+convertedDateStr);
convertedTime = sdf.parse(convertedDateStr);
System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
}catch(Exception e){
e.printStackTrace();
}
return convertedTime;
}
I would appreciate if anyone could help and point out where I am going wrong.
Thanks in advance.
Output:
timezone: Atlantic/Cape_Verde, timestamp: Tue Jun 26 17:38:11 IST 2012
Source timezone: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]
convertedDateStr: 2012-06-26 11:08:11
convertedTime: Tue Jun 26 17:38:11 IST 2012
sdf:sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]
Some more details to share, When I use another sdf object(without setting timezone for it), It do return me correct time and date but still timezone is picked from System clock
Code
static Date convertGMTTime(String timeZone, long longDate){
Date convertedTime = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdfParse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
Date date = new Date(longDate);
TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
System.out.println("Source timezone: "+destTimeZone);
sdf.setTimeZone(destTimeZone);
String convertedDateStr = sdf.format(date);
System.out.println("convertedDateStr: "+convertedDateStr );
convertedTime = sdfParse.parse(convertedDateStr,new ParsePosition(0));
System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
}catch(Exception e){
e.printStackTrace();
}
return convertedTime;
}
Output
Source timezone: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]
convertedDateStr: 2012-06-26 12:24:56
convertedTime: Tue Jun 26 12:24:56 IST 2012
sdf: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]
I understand that when I do not assign timezone to sdf it takes System time zone, but why doesn't it show time in System time zone? I shows it in timezone as it was in String but Timezone is different.
Ans when I set timezone it returns date object as per my system time irrespective of the fact that sdf has some other time zone set.
Can anyone please explain the functional behavior for sdf.parse and sdf.format.
For me sdf.setTimeZone() does have its impact when we use format and it is nullified when we use sdf.parse(). I find it quite strange.
Appreciate help in this regard.
You already have a Date (or the number of milliseconds of the Date), so there is nothing to convert. A Date doesn't have any time zone. It's a universal instant in time. The time zone is relevant only when you display this date, because the date 65647678000 could be 12:38 in some time zone, but 10:38 in some other time zone. It's also relevant when you parse the String representation of a Date, because 10:38 is 65647678000 in some time zone, but is 65657678000 in some other.
While you don't display a Date object, or parse a String to a Date, you don't need to care about time zones. And to choose the time zone used when displaying/parsing it, set the time zone of the DateFormat, and then use DateFormat.format()/DateFormat.parse() to format/parse the date.
When you use Date.toString() to display a date, it will always use your current time zone.
I find it easier to understand what I mean by not thinking of a Date as a day, a month, a year, an hour, etc., but as a moment: "when Kennedy was shot". "When Kennedy was shot" is the same moment for everyone. But if you represent the moment "when Kennedy was shot" in Dallas time zone, it's not the same result as the result you get when you represent this same moment in Paris time zone.
I need a Java program to get the current date without a timestamp:
Date d = new Date();
gives me date and timestamp.
But I need only the date, without a timestamp. I use this date to compare with another date object that does not have a timestamp.
On printing
System.out.println("Current Date : " + d)
of d it should print May 11 2010 - 00:00:00.
A java.util.Date object is a kind of timestamp - it contains a number of milliseconds since January 1, 1970, 00:00:00 UTC. So you can't use a standard Date object to contain just a day / month / year, without a time.
As far as I know, there's no really easy way to compare dates by only taking the date (and not the time) into account in the standard Java API. You can use class Calendar and clear the hour, minutes, seconds and milliseconds:
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.HOUR_OF_DAY);
cal.clear(Calendar.AM_PM);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
Do the same with another Calendar object that contains the date that you want to compare it to, and use the after() or before() methods to do the comparison.
As explained into the Javadoc of java.util.Calendar.clear(int field):
The HOUR_OF_DAY, HOUR and AM_PM fields are handled independently and the the resolution rule for the time of day is applied. Clearing one of the fields doesn't reset the hour of day value of this Calendar. Use set(Calendar.HOUR_OF_DAY, 0) to reset the hour value.
edit - The answer above is from 2010; in Java 8, there is a new date and time API in the package java.time which is much more powerful and useful than the old java.util.Date and java.util.Calendar classes. Use the new date and time classes instead of the old ones.
You could always use apache commons' DateUtils class. It has the static method isSameDay() which "Checks if two date objects are on the same day ignoring time."
static boolean isSameDay(Date date1, Date date2)
Use DateFormat to solve this problem:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
DateFormat dateFormat2 = new SimpleDateFormat("MM-dd-yyyy");
print(dateFormat.format(new Date()); // will print like 2014-02-20
print(dateFormat2.format(new Date()); // will print like 02-20-2014
I did as follows and it worked: (Current date without timestamp)
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date today = dateFormat.parse(dateFormat.format(new Date()));
DateFormat dateFormat = new SimpleDateFormat("MMMM dd yyyy");
java.util.Date date = new java.util.Date();
System.out.println("Current Date : " + dateFormat.format(date));
You can get by this date:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
print(dateFormat.format(new Date());
You could use
// Format a string containing a date.
import java.util.Calendar;
import java.util.GregorianCalendar;
import static java.util.Calendar.*;
Calendar c = GregorianCalendar.getInstance();
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
// -> s == "Duke's Birthday: May 23, 1995"
Have a look at the Formatter API documentation.
The accepted answer by Jesper is correct but now outdated. The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them.
java.time
Instead use the java.time framework, built into Java 8 and later, back-ported to Java 6 & 7 and further adapted to Android.
If you truly do not care about time-of-day and time zones, use LocalDate in the java.time framework ().
LocalDate localDate = LocalDate.of( 2014 , 5 , 6 );
Today
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 ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
LocalDate today = LocalDate.now( z ) ;
Moment
If you care about specific moments, specific points on the timeline, do not use LocalDate. If you care about the date as seen through the wall-clock time used by the people of a certain region, do not use LocalDate.
Be aware that if you have any chance of needing to deal with other time zones or UTC, this is the wrong way to go. Naïve programmers tend to think they do not need time zones when in fact they do.
Strings
Call toString to generate a string in standard ISO 8601 format.
String output = localDate.toString();
2014-05-06
For other formats, search Stack Overflow for DateTimeFormatter class.
Joda-Time
Though now supplanted by java.time, you can use the similar LocalDate class in the Joda-Time library (the inspiration for java.time).
LocalDate localDate = new LocalDate( 2014, 5, 6 );
Also you can use apache commons lib DateUtils.truncate():
Date now = new Date();
Date truncated = DateUtils.truncate(now, Calendar.DAY_OF_MONTH);
Time will be set to 00:00:00 so you can work with this date or print it formatted:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateFormat.format(now); // 2010-05-11 11:32:47
System.out.println(dateFormat.format(truncated); // 2010-05-11 00:00:00
private static final DateFormat df1 = new SimpleDateFormat("yyyyMMdd");
private static Date NOW = new Date();
static {
try {
NOW = df1.parse(df1.format(new Date()));
} catch (ParseException e) {
e.printStackTrace();
}
}
I think this will work. Use Calendar to manipulate time fields (reset them to zero), then get the Date from the Calendar.
Calendar c = GregorianCalendar.getInstance();
c.clear( Calendar.HOUR_OF_DAY );
c.clear( Calendar.MINUTE );
c.clear( Calendar.SECOND );
c.clear( Calendar.MILLISECOND );
Date today = c.getTime();
Or do the opposite. Put the date you want to compare to in a calendar and compare calendar dates
Date compareToDate; // assume this is set before going in.
Calendar today = GregorianCalendar.getInstance();
Calendar compareTo = GregorianCalendar.getInstance();
compareTo.setTime( compareToDate );
if( today.get( Calendar.YEAR ) == compareTo.get( Calendar.YEAR ) &&
today.get( Calendar.DAY_OF_YEAR ) == compareTo.get( Calendar.DAY_OF_YEAR ) ) {
// They are the same day!
}
Here's an inelegant way of doing it quick without additional dependencies.
You could just use java.sql.Date, which extends java.util.Date although for comparisons you will have to compare the Strings.
java.sql.Date dt1 = new java.sql.Date(System.currentTimeMillis());
String dt1Text = dt1.toString();
System.out.println("Current Date1 : " + dt1Text);
Thread.sleep(2000);
java.sql.Date dt2 = new java.sql.Date(System.currentTimeMillis());
String dt2Text = dt2.toString();
System.out.println("Current Date2 : " + dt2Text);
boolean dateResult = dt1.equals(dt2);
System.out.println("Date comparison is " + dateResult);
boolean stringResult = dt1Text.equals(dt2Text);
System.out.println("String comparison is " + stringResult);
Output:
Current Date1 : 2010-05-10
Current Date2 : 2010-05-10
Date comparison is false
String comparison is true
If you really want to use a Date instead for a Calendar for comparison, this is the shortest piece of code you could use:
Calendar c = Calendar.getInstance();
Date d = new GregorianCalendar(c.get(Calendar.YEAR),
c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH)).getTime();
This way you make sure the hours/minute/second/millisecond values are blank.
I did as follows and it worked:
calendar1.set(Calendar.HOUR_OF_DAY, 0);
calendar1.set(Calendar.AM_PM, 0);
calendar1.set(Calendar.HOUR, 0);
calendar1.set(Calendar.MINUTE, 0);
calendar1.set(Calendar.SECOND, 0);
calendar1.set(Calendar.MILLISECOND, 0);
Date date1 = calendar1.getTime(); // Convert it to date
Do this for other instances to which you want to compare. This logic worked for me; I had to compare the dates whether they are equal or not, but you can do different comparisons (before, after, equals, etc.)
I was looking for the same solution and the following worked for me.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.clear(Calendar.HOUR);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
Date today = calendar.getTime();
Please note that I am using calendar.set(Calendar.HOUR_OF_DAY, 0) for HOUR_OF_DAY instead of using the clear method, because it is suggested in Calendar.clear method's javadocs as the following
The HOUR_OF_DAY, HOUR and AM_PM fields are handled independently and
the the resolution rule for the time of day is applied. Clearing one
of the fields doesn't reset the hour of day value of this Calendar.
Use set(Calendar.HOUR_OF_DAY, 0) to reset the hour value.
With the above posted solution I get output as
Wed Sep 11 00:00:00 EDT 2013
Using clear method for HOUR_OF_DAY resets hour at 12 when executing after 12PM or 00 when executing before 12PM.
Here is my code for get only date:
Calendar c=Calendar.getInstance();
DateFormat dm = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date date = new java.util.Date();
System.out.println("current date is : " + dm.format(date));
Here is full Example of it.But you have to cast Sting back to Date.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//TODO OutPut should LIKE in this format MM dd yyyy HH:mm:ss.SSSSSS
public class TestDateExample {
public static void main(String args[]) throws ParseException {
SimpleDateFormat changeFormat = new SimpleDateFormat("MM dd yyyy HH:mm:ss.SSSSSS");
Date thisDate = new Date();//changeFormat.parse("10 07 2012");
System.out.println("Current Date : " + thisDate);
changeFormat.format(thisDate);
System.out.println("----------------------------");
System.out.println("After applying formating :");
String strDateOutput = changeFormat.format(thisDate);
System.out.println(strDateOutput);
}
}