I need to get today’s date at midnight in my time zone in the format YYYYMMDDHHMMss.000Z as date and time in GMT.
I'm interested in the date, not the time of day.
In my system when I have got a date: 20201001220000.000Z it is a day 20201003 as summertime for GMT. I am asking this question because I need to compare the 20201001220000.000Z with today’s date.
I need to get the date ( TODAY midnight) in format yyyyMMddHHmmss.SSSZ. TODAY midnight 20201004 in my system is: 20201003220000.000Z this date will be compared with other dates e.g 20201002220000.000Z. The problem is that I can't get midnight.
java.time
Edit:
I tend to understand that you want to format today’s date into your format for comparison with other date-time strings in UTC (GMT) in the same format. For comparing dates and times I suggest that you compare date-time objects, not strings. So the options are two:
Parse the existing string, convert it to a date in your time zone and compare it to today’s date.
Parse your existing string into a point in time. Compare to the start of today’s date.
Let’s see both options in code.
1. Convert to date and compare dates:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SSSX");
ZoneId zone = ZoneId.systemDefault();
LocalDate today = LocalDate.now(zone);
String gmtString = "20201001220000.000Z";
LocalDate dateFromGmtString = formatter.parse(gmtString, Instant::from)
.atZone(zone)
.toLocalDate();
if (dateFromGmtString.isAfter(today)) {
System.out.println(gmtString + " is in the future");
} else if (dateFromGmtString.isBefore(today)) {
System.out.println(gmtString + " was on a past date");
} else {
System.out.println(gmtString + " is today");
}
Output:
20201001220000.000Z was on a past date
2. Find start of today’s date and compare times
Instant startOfDay = LocalDate.now(zone).atStartOfDay(zone).toInstant();
String gmtString = "20201001220000.000Z";
Instant timeFromGmtString = formatter.parse(gmtString, Instant::from);
if (timeFromGmtString.isBefore(startOfDay)) {
System.out.println(gmtString + " was on a past date");
} else {
System.out.println(gmtString + " is today or later");
}
20201001220000.000Z was on a past date
Original answer
You may be after the following. I recommend that you use java.time, the modern Java date and time API, for your date and time work.
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SSSX");
String gmtString = "20201001220000.000Z";
Instant instant = sourceFormatter.parse(gmtString, Instant::from);
LocalDate date = instant.atZone(ZoneId.systemDefault()).toLocalDate();
String dayString = date.format(DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(dayString);
When I run the code in Europe/Warsaw time zone, the output is:
20201002
So the date has been converted from October 1 GMT to October 2 in Poland.
Edit:
… How can I get midnight?
To get the start of the day (usually 00:00):
ZonedDateTime startOfDay = time.atZone(ZoneId.systemDefault())
.truncatedTo(ChronoUnit.DAYS);
System.out.println(startOfDay);
2020-10-02T00:00+02:00[Europe/Warsaw]
Link: Oracle tutorial: Date Time explaining how to use java.time.
Try this.
String format = "yyyy-MM-dd HH:mm:ss.SSS O";
ZonedDateTime zdt = ZonedDateTime.now().withZoneSameInstant(ZoneId.of("GMT"));
System.out.println(zdt.format(DateTimeFormatter.ofPattern(format)));
Prints a US East coast time as
2020-10-03 14:47:18.809 GMT
You can delete the spaces, dashes and colons as desired. But do not use Date or related formatters as they are outdated. Use the classes from the java.time package.
You can do it as follows:
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Today
LocalDate today = LocalDate.now();
// Midnight in the JVM's default time-zone
ZonedDateTime zdt = today.atStartOfDay(ZoneId.systemDefault());
// Printing zdt in its default format i.e. value returned by zdt.toString()
System.out.println(zdt);
// Printing zdt in your custom format
DateTimeFormatter customFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSSZ");
String dateTimeStrCustom = zdt.format(customFormat);
System.out.println(dateTimeStrCustom);
}
}
Output:
2020-10-04T00:00+01:00[Europe/London]
20201004000000.000+0100
Related
I currently have a Date e.g. "2015-10-10T14:34:22Z". I need the year from the Date object for my new LocalDateTime object as this object will be set to that Date object year and have a specific month, day and time set (yyyy-06-15T17:00:00Z).
Taking the getYear() from Date has the 1900 issue.
I get the date via LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
Create another object to set the desired month and day
Create LocalDateTime object to set the time
I feel I am doing it a very long convuluted way and would like to ask if there are any other shorter and better alternatives.
EDIT:
Are there are any other shorter and better alternatives?
Since your date-time string has timezone offset information. So, you can parse it to an OffsetDateTime object and then get the year from it.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2015-10-10T14:34:22Z";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note that Z in the date-time string stands for Zulu date-time and specifies a timezone offset of +00:00 hours or date-time at UTC.
Taking the getYear() from Date has the 1900 issue.
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Converting from legacy API to the modern API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
String strDateTime = "2015-10-10T14:34:22Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = sdf.parse(strDateTime);
Instant instant = date.toInstant();
OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
System.out.println(odt);
System.out.println(odt.getYear());
// If you want to get LocalDateTime from OffsetDateTime
LocalDateTime ldt = odt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2015-10-10T14:34:22Z
2015
2015-10-10T14:34:22
Note: If you want to convert the Instant into ZonedDateTime at UTC, you can do it as follows:
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
or the following:
ZonedDateTime zdt = instant.atZone(ZoneId.of("Etc/UTC"));
Note that the three-letter name for a ZoneId is error-prone i.e. avoid using something like ZoneId.of("UTC").
What is wrong with your code:
You are using .atZone(ZoneId.systemDefault()) which is converting the object of Instant to an object of ZonedDateTime with your JVM's timezone. You have to use .atOffset(ZoneOffset.UTC) as shown above to keep the date-time with the same timezone offset (i.e. +00:00 hours or date-time at UTC) which is there in the date-time string.
try this :
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX");
try {
String s = "2015-10-10T14:34:22+02";
s = s.replaceAll("T", " ");
Date d = df.parse(s);
Calendar cl = Calendar.getInstance();
cl.setTime(d);
System.out.println(cl.getTime());
System.out.println("year : " + cl.get(Calendar.YEAR));
} catch (ParseException e) {
System.err.println(e);
}
output
Sat Oct 10 13:34:22 GMT+01:00 2015
year : 2015
Maybe this approach could help:
import java.text.ParseException;
import java.time.*;
import java.util.Date;
public class ConvertDate {
public static void main(String[] args) throws ParseException {
Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atOffset(ZoneOffset.UTC).toLocalDateTime();
System.out.println(localDateTime);
System.out.println(localDateTime.getYear());
}
}
Time zone is crucial
You need to decide in which time zone you want the year. New Year doesn’t happen at one point in time across the globe, but over a span of about 26 hours. So if your date string is within a day or so of New Year, your result could be off by a year if you don’t pick the correct time zone. For example:
ZoneId zone = ZoneId.of("America/Louisville");
// The year in the following object does not matter
ZonedDateTime fixedTimeOfYear = ZonedDateTime.of(2020, 6, 15, 17, 0, 0, 0, zone);
String inputString = "2015-01-01T01:02:03Z";
OffsetDateTime input = OffsetDateTime.parse(inputString);
int year = input.atZoneSameInstant(zone).getYear();
System.out.format("Year in %s is %d%n", zone, year);
ZonedDateTime desiredTime = fixedTimeOfYear.withYear(year);
System.out.println("Result: " + desiredTime);
Output from this snippet is:
Year in America/Louisville is 2014
Result: 2014-06-15T17:00-04:00[America/Louisville]
You notice that even though the year in the string is 2015, it is still only 2014 in the time zone that I chose for the demonstration, so the resulting date and time are in 2014. The example was picked to demonstrate my point.
Don’t use LocalDateTime
The frequent use of LocalDateTime that you mention in a comment is a misunderstanding. For a date and time in a known time zone in 2015, for example, LocalDateTime is the wrong class to use. Use ZonedDateTime or at least OffsetDateTime so we know what we are talking about. These classes have the advantages that they keep track of time zone or offset themselves, and that they define an unambiguous point in time. LocalDateTime does nothing of this.
Getting a DateTimeParseExcpetion when trying to convert the String 2020-04-01T08:53:47.000+02:00 00:00
String date = "2020-04-01T08:53:47.000+02:00 00:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
parsedDate = LocalDateTime.parse(date,formatter).toString();
System.out.println(parsedDate);
Your pattern is not the same as your String. Check the last part where is 000+02:00 00:00.
Your pattern is: SSSz
If you try this:
String date = "2020-04-01T08:53:47.000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
It will works because your date is like your pattern. Note that every number in the date is into pattern too.
But for your date there is an empty space what no make sense, so removing it, the code works perfectly.
String date = "2020-04-01T08:53:47.000+02:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz");
Output:
2020-04-01T08:53:47
Note that z is the local time and means "zero hour offset" or "Zulu time" (UTC) and you can use Locale.
The 00:00 at the end of your date-time string doesn't make sense to me. Parse the date-time string after stripping that.
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDate = "2020-04-01T08:53:47.000+02:00 00:00";
strDate = strDate.substring(0, strDate.lastIndexOf(' '));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSz", Locale.ENGLISH);
LocalDateTime parsedDate = LocalDateTime.parse(strDate, formatter);
System.out.println(parsedDate);
OffsetDateTime odt = OffsetDateTime.parse(strDate);
System.out.println(odt);
System.out.println(odt.getOffset());
}
}
Output:
2020-04-01T08:53:47
2020-04-01T08:53:47+02:00
+02:00
Note: You can parse your date-time string (after striping 00:00 from the end of it) to OffsetDateTime in order to preserve the zone-offset information.
Use the built-in formatter
The built-in DateTimeFormatter.ISO_OFFSET_DATE_TIME matches the part of your string that we can understand. And it can parse just that part and ignore the rest.
String date = "2020-04-01T08:53:47.000+02:00 00:00";
ParsePosition pp = new ParsePosition(0);
OffsetDateTime odt = OffsetDateTime.from(
DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(date, pp));
System.out.println("Date and time: " + odt);
System.out.println("Unparsed text: " + date.substring(pp.getIndex()));
Output:
Date and time: 2020-04-01T08:53:47+02:00
Unparsed text: 00:00
Since your string contains an offset from UTC, OffsetDateTime is the correct class to parse into. If we used LocalDateTIme, the offset would be ignored, and we would end up not knowing at which offset the time was to be interpreted, that is, we could not know which point in time it was. With OffsetDateTime the point in time is unambiguous. If you want to convert to the time in your own time zone, convert to ZonedDateTime (still not LocalDateTime).
ZonedDateTime timeInMyTimeZone = odt.atZoneSameInstant(ZoneId.systemDefault());
System.out.println("Date and time: " + timeInMyTimeZone);
Example output:
Date and time: 2020-04-01T11:53:47+05:00[Asia/Aqtobe]
Links
Documentation links:
DateTimeFormatter.ISO_OFFSET_DATE_TIME.
The two-arg DateTimeFormatter.parse(CharSequence, ParsePosition) that I used.
I need to get the datetime of 1 year back considering the current datetime. The format needed to be in "yyyy-MM-dd HH:mm:ss.SSS"
ex : 2019-08-13 12:00:14.326
I tried following. But getting an error.
LocalDate now = LocalDate.now();
LocalDate localDate = LocalDate.parse(now.toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")).minusYears(1);
Below Exception returned:
DateTimeParseException: Text '2020-08-13' could not be parsed
What's the best way to do this in Java 8+ ?
A LocalDate does not hold any information about hours, minutes, seconds or any unit below, instead, it holds information about year, month and day. By calling LocalDate.now() you are getting the date of today (the day of code execution).
If you need the time as well, use a LocalDateTime, which has a method now(), too, and actually consists of a LocalDate and a LocalTime.
Your error message tells you that the content of a LocalDate cannot be formatted using the given pattern (-String) "yyyy-MM-dd HH:mm:ss.SSS" because that pattern requires values for hours (HH), minutes (mm), seconds (ss) and milliseconds (SSS are fraction of seconds and three of them make it be milliseconds).
For parsing Strings or formatting datetimes, a LocalDateTime may be suitable but if you want to reliably add or subtract a year or any other amount of time, you'd rather use a class that considers time zones, offsets and daylight saving like ZonedDateTime or OffsetDateTime...
The LocalDate is the wrong class for your requirement as it does not hold the time information. You can use LocalDateTime but I suggest you use OffsetDateTime or ZonedDateTime so that you can get the flexibility of using the Zone Offset and Zone ID. Check https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html for an overview of date-time classes.
Also, keep in mind that a date or time or date-time object is an object that just holds the information about date/time; it doesn't hold any information about formatting and therefore no matter what you do when you print their objects, you will always get the output what their toString() methods return. In order to format these classes or in other words, to get a string representing a custom format of these objects, you have formatting API (e.g. the modern DateTimeFormatter or legacy SimpleDateFormat) at your disposal.
A sample code:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Get the current date & time at UTC
OffsetDateTime odtNow = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println("Now at UTC: " + odtNow);
// Get the date & time one year ago from now at UTC
OffsetDateTime odtOneYearAgo = odtNow.minusYears(1);
System.out.println("One year ago at UTC: " + odtNow);
// Define a formatter for the output in the desired pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
// Format the date & time using your defined formatter
String formattedDateTimeOneYearAgo = formatter.format(odtOneYearAgo);
System.out.println("Date Time in the pattern, yyyy-MM-dd HH:mm:ss.SSS: " + formattedDateTimeOneYearAgo);
}
}
Output:
Now at UTC: 2020-08-13T08:50:36.277895Z
One year ago at UTC: 2020-08-13T08:50:36.277895Z
Date Time in the pattern, yyyy-MM-dd HH:mm:ss.SSS: 2019-08-13 08:50:36.277
May not be the best way, but this will do it
LocalDateTime date = LocalDateTime.now().minusYears(1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(date.format(formatter));
You say you want date+time from 1 year back, but you give it only a date (LocalDate). If you just want the date, all you need to do is:
LocalDate now = LocalDate.now();
LocalDate then = now.minusYears(1);
And if you want the timestamp also, then:
LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.minusYears(1);
And so on for other objects.
As mentioned you should use LocalDateTime instead of LocalDate.
Your exception was thrown because your input String is in ISO_DATE_TIME format
Java Doc
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
String now = dateTimeFormatter.format(LocalDateTime.now());
LocalDateTime localDate = LocalDateTime.parse(now, dateTimeFormatter);
I'm trying to convert PST timestamp to epoch time.
The first method I tried is using zoned datetime by passing America/Los Angeles as input time zone.
public static void changeStringDateFormatToEpoch(String oldDate, String format) throws ParseException {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
LocalDateTime dt = LocalDateTime.parse(oldDate, dtf);
ZonedDateTime zdtzone = dt.atZone(ZoneId.of("America/Los_Angeles"));
System.out.println("When date: "+ oldDate + " is in format "+ format + " --> " + zdtzone.toEpochSecond());
}
After this I tried running the below code which uses SimpleDateFormat to do the same
public static void changeStringDateFormatToEpochSimpleDate(String oldDate, String format) throws ParseException{
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date dt = sdf.parse(oldDate);
long epoch = dt. getTime();
System.out.println("When date: "+ oldDate + " is in format "+ format + " --> " + epoch);
}
How is that both the outputs are similar, when in the 2nd case I'm not even specifying the timezone of the input date.
Shouldn't the epoch time get affected since the input time zone is PST(America/Los Angeles)?
sample input
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
class Scratch {
public static void main(String[] args) {
String date = "2019-11-27 04:32:41.000-0800"; //yyyy-MM-dd HH:mm:ss.SSSZ
String date2 = "2019-11-27 04:32:41"; // yyyy-MM-dd HH:mm:ss
try {
changeStringDateFormatToEpoch(date, "yyyy-MM-dd HH:mm:ss.SSSZ");
changeStringDateFormatToEpoch(date2, "yyyy-MM-dd HH:mm:ss");
changeStringDateFormatToEpochSimpleDate(date, "yyyy-MM-dd HH:mm:ss.SSSZ");
changeStringDateFormatToEpochSimpleDate(date2, "yyyy-MM-dd HH:mm:ss");
} catch (ParseException e) {
e.printStackTrace();
}
}
public static void changeStringDateFormatToEpoch(String oldDate, String format) throws ParseException {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
LocalDateTime dt = LocalDateTime.parse(oldDate, dtf);
ZonedDateTime zdtzone = dt.atZone(ZoneId.of("America/Los_Angeles"));
System.out.println("When date: "+ oldDate + " is in format "+ format + " --> " + zdtzone.toEpochSecond());
}
public static void changeStringDateFormatToEpochSimpleDate(String oldDate, String format) throws ParseException{
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date dt = sdf.parse(oldDate);
long epoch = dt. getTime();
System.out.println("SimpleDate : When date: "+ oldDate + " is in format "+ format + " --> " + epoch);
}
}
output
When date: 2019-11-27 04:32:41.000-0800 is in format yyyy-MM-dd HH:mm:ss.SSSZ --> 1574857961
When date: 2019-11-27 04:32:41 is in format yyyy-MM-dd HH:mm:ss --> 1574857961
SimpleDate : When date: 2019-11-27 04:32:41.000-0800 is in format yyyy-MM-dd HH:mm:ss.SSSZ --> 1574857961000
SimpleDate : When date: 2019-11-27 04:32:41 is in format yyyy-MM-dd HH:mm:ss --> 1574857961000
Your SimpleDateFormat-based code works as expected only because you are running it on machine in the Pacific time zone. SimpleDateFormat instances are initialized with the system default time zone, but it can be changed.
To make your code robust and portable, use the first approach. Parse a LocalDateTime, and then combine it with an explicit ZoneId, rather than inferring the default time zone.
Some of the date times parsed in your example use an offset date-time. This is helpful; many developers in zones afflicted by daylight-saving time overlook the need to include some indication whether daylight saving is currently in effect when storing local time stamps. Without it, there is ambiguity in parsing times during the autumn transition to standard time.
In any case, you should be aware that it is also possible to combine a LocalDateTime with a ZoneOffset to produce an OffsetDateTime, and from that, an epoch time.
After editing your changeStringDateFormatToEpoch() has a new problem: it is now ignoring the offset -0800 given in the string. As long as it happens to agree with the time zone you provide hardcoded in the code, the result is OK; but if the offset had been different, you would have obtained an incorrect result. Even for America/Los_Angeles time zone you will get an incorrect result at the overlap when summer time (DST) ends, clock times are repeated and the offset is your only chance of distinguishing.
The code using SimpleDateFormat can be said to have the opposite problem: in case of an absent time zone or offset it uses the JVM’s default time zone, which may or may not be the intended. Chances are further harmed by the fact that the JVM time zone setting can be changed at any time by another part of your program or another program running in the same JVM.
If you know that America/Los Angeles time zone will be intended for strings without zone or offset, the solution is this variant:
/** #throws DateTimeParseException if oldDate is not in the format given */
public static void changeStringDateFormatToEpoch(String oldDate, String format) {
// Time zone to use if neither time zone nor UTC offset is given in the string
ZoneId defaultZone = ZoneId.of("America/Los_Angeles");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format).withZone(defaultZone);
ZonedDateTime zdt = ZonedDateTime.parse(oldDate, dtf);
System.out.println("When date: " + oldDate + " is in format " + format
+ " --> " + zdt.toEpochSecond());
}
Let’s try it out using your own code:
String date = "2019-11-27 04:32:41.000-0800"; //yyyy-MM-dd HH:mm:ss.SSSZ
String date2 = "2019-11-27 04:32:41"; // yyyy-MM-dd HH:mm:ss
changeStringDateFormatToEpoch(date, "yyyy-MM-dd HH:mm:ss.SSSZ");
changeStringDateFormatToEpoch(date2, "yyyy-MM-dd HH:mm:ss");
Even when running in my time zone, Europe/Copenhagen, the results agree:
When date: 2019-11-27 04:32:41.000-0800 is in format yyyy-MM-dd HH:mm:ss.SSSZ --> 1574857961
When date: 2019-11-27 04:32:41 is in format yyyy-MM-dd HH:mm:ss --> 1574857961
To answer your questions
How is that both the outputs are similar, when in the 2nd case I'm not
even specifying the timezone of the input date.
In the second case SimpleDateFormat uses the time zone setting of your JVM. Only because this is America/Los_Angeles (or another time zone that uses offset -08:00 on November 27) do the outputs agree. When running in a different time zone they would not.
Shouldn't the epoch time get affected since the input time zone is
PST(America/Los Angeles)?
The output is affected by the JVM’s default time zone. It doesn’t use UTC or some other default unless the default is set so.
Do not use SimpleDateFormat
The SimpleDateFormat class is notoriously troublesome and long outdated. It’s somehow not surprising that it gives you a surprising result. Do use java.time, the modern Java date and time API that ZonedDateTime is a part of for your date and time work. It tends to give a lot fewer surprises and more natural code.
ZonedDateTime zonedDateTime = LocalDateTime.now().atZone(ZoneId.of("Asia/Hong_Kong"));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy - hh:mm:ss zzz");
String formattedString = zonedDateTime.format(dateTimeFormatter);
System.out.println(String.format("ZonedDateTime [%s], Formatted ZonedDateTime [%s]", zonedDateTime, formattedString));
output is - ZonedDateTime [2022-03-17T17:09:27.471+08:00[Asia/Hong_Kong]], Formatted ZonedDateTime [03/17/2022 - 05:09:27 HKT]
but when i do
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/mm/yyyy - hh:mm:ss zzz");
String format = simpleDateFormat.format(zonedDateTime);
System.out.println(format);
throw error
Cannot format given Object as a Date
Which means SimpleDateFormat is not support ZonedDateTime ?
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);
}
}