Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I work with the date in my API on Java. I want to get today's date and time, write it to a class and then to a csv file (I use a csv file as a data store). Then, to implement the function of getting a report on records for today, to get it and to compare it with today's date (exactly the date, without time). What is the best way to do this? Right now I'm storing this in Timestamp, but it doesn't seem to be correct and should I use String? Then I need two parsers? To translate from a string to a date and time and from that to just a DATE? Which library is better to use for this?
I wrote a translation from a string to a timestamp, is this correct?
default Timestamp StringToTimestamp(String date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-YYYY");
Date parsedDate = null;
try {
parsedDate = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
log.error("Error in date parsing");
}
return new Timestamp(parsedDate.getTime());
}
UPD
I changed my code for the java.time library, but it seems I did something wrong
default LocalDate StringToTimestamp(String date) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern('yyyy-mm-dd');
LocalDate date = LocalDate.parse(date, dtf);
return date;
}
UPD I edited the code according to the answer #OleV.V. It works really cool
java.time
I recommend that you use java.time, the modern Java date and time API, for your date and time work. I suggest writing the current date and time with offset from UTC to the CSV file.
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.systemDefault());
String stringForCsvFile = dateTime.toString();
System.out.println(stringForCsvFile);
Output when running in my time zone just now:
2020-12-26T11:02:07.368973+01:00
The string is in ISO 8601 format, which should be the best to avoid surprises for anyone reading it. The classes of java.time generally print ISO 8601 format from their toString methods.
Often you will value consistency higher than knowing which UTC offset was used when writing the file. If so, write the time in UTC to the file:
Instant now = Instant.now();
String stringForCsvFile = now.toString();
2020-12-26T10:02:07.373439Z
No matter which way you used above, after reading the timestamp from the file, convert like this:
ZoneId zone = ZoneId.systemDefault();
String stringFromCsvFile = "2020-12-26T11:02:07.368973+01:00";
ZonedDateTime dateTime = OffsetDateTime.parse(stringFromCsvFile)
.atZoneSameInstant(zone);
LocalDate dateFromCsv = dateTime.toLocalDate();
LocalDate today = LocalDate.now(zone);
System.out.println("Same day? " + dateFromCsv.isEqual(today));
Same day? true
I have made sure that both dates I compare are in the time zone of the JVM where the program is running. Please consider whether there’s a specific time zone you want, and if so, set zone to something like ZoneId.of("Asia/Baku"). It matters: it is never the same date in all time zones.
If you want to know whether the date is earlier or later, use the isBefore or isAfter method of LocalDate.
Was your code correct?
IMHO the worst problem with your code is using the old and poorly designed date-time classes: SimpleDateFormat, Date and Timestamp. SimpleDateFormat is a notorious troublemaker of a class. Date had severe design flaws in Java 1.0, therefore most constructors and methods were deprecated already in Java 1.1. Timestamp was never meant for other purposes than transferring high-precision timestamps to and from SQL databases (which we also don’t use it for anymore). And it’s a true hack on top of the already poorly designed Date class. I furthermore see nothing that you will want to use the high precision of Timestamp for, so using it here seems pointless.
There is a bug in your code: You are using upper case YYYY in your format pattern. This is for week year and only useful with a week number. I tried giving 24-06-2021 to your method. It returned 2021-01-04 00:00:00.0. It’s 5 months 20 days off because of the mentioned error. Apparently SimpleDateFormat defaulted to the start of week 1 in the week year and ignored the month and day of month.
As an aside, had you tried parsing with the same format pattern string with java.time, it would at least have told you that this was wrong.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Related question: java parsing string to date
Related
This question already has answers here:
How to set time zone of a java.util.Date?
(12 answers)
Closed 2 years ago.
I have a java.util.Date object. When I format it to String using:
String timeString = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss-Z").format(time);
I get:
2020-03-26-14:40:55-+0200
So, I somehow have the correct time zone (but I can have any time zone, not only +2), this is good.
I want to convert this date to UTC, and then convert it to String. If I send an object with a date to the client, then Jackson will automatically convert it to UTC. But I want to do this manually.
How can I do this?
It is not recommended anymore to use java.util for date-time operations, especially not for time-zone or offset conversions...
Instead, use java.time:
public static void main(String[] args) {
// the String (with a strange formatting) to be parsed
String datetime = "2020-03-26-14:40:55-+0200";
// parse it to an OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(datetime,
// using a formatter for this specific pattern
DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-x"));
// print the parsing result
System.out.println(odt);
// then convert it to UTC (keeping the moment & adjusting the offset)
OffsetDateTime odtUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
// print the conversion result
System.out.println(odtUtc);
}
gives you the following output
2020-03-26T14:40:55+02:00
2020-03-26T12:40:55Z
java.time
I understand that you have got a field of type java.util.Date that you cannot afford to change just now. For any operation on that Date you should still convert it to a modern Instant first and then do your further work from there. For converting it to a string in UTC you may use the very simple:
String timeString = yourJavaUtilDate.toInstant().toString();
System.out.println(timeString);
Example output:
2020-03-26T12:40:55Z
While an Instant is a point in time without time zone or offset, just like a Date is, Instant.toString() produces a string in UTC in ISO 8601 format, which I find quite nice. If you wanted the peculiar format mentioned in your question (you must have very special reasons for that):
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-Z");
String timeString = yourJavaUtilDate.toInstant()
.atOffset(ZoneOffset.UTC)
.format(formatter);
2020-03-26-12:40:55-+0000
Your format pattern string from SimpleDateFormat works with the modern DateTimeFormatter too. That is not always the case, there are differences between the sets of format pattern letters for the two, only many of the letters have the same or similar meaning.
I am myself working with a very old code base that over the years has acquired a messy mixture of outdated and modern date and time classes. So we’re constantly converting back and forth between Date, LocalDate, OffsetDateTime, XMLGregorianCalendar and many other classes, which is far from ideal, and it will take some years still to get to the sweet spot where we will be using the modern classes only.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
This question already has answers here:
want current date and time in "dd/MM/yyyy HH:mm:ss.SS" format
(11 answers)
Closed 4 years ago.
I am trying to convert a java.util.Date to XMLGregorianCalendar in Italian format (dd/mm/yyyy) with no time. Whatever I try the output always prints yyyy-mm-dd.
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Rome"));
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),
DatatypeConstants.FIELD_UNDEFINED);
System.out.println(xmlDate);
I am a consumer of SOAP web-service, and the date attribute is defined as XMLGregorianCalendar.
Please advise how can I change the code to get the output with format (dd/mm/yyyy).
You don’t need an XMLGregorianCalender. It will not, cannot give you what you ask for. Instead you need a LocalDate and a DateTimeFormatter:
DateTimeFormatter italianDateFormatter
= DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.ITALIAN);
LocalDate date = LocalDate.now(ZoneId.of("Europe/Rome"));
String formattedDate = date.format(italianDateFormatter);
System.out.println(formattedDate);
When I ran this code today, the output was:
21/01/19
The difference from what you ask for is the two digit year, 19. If instead of FormatStyle.SHORT we use FormatStyle.MEDIUM, we get four digit year, but the month as a three letter abbreviaiton:
21-gen-2019
The advantage is that the code lends itself very well to internationalization: you just need to change the locale to get proper code for some other language and country. If you do need 21/01/2019 (with four digit year), specify the format explicitly using a pattern:
DateTimeFormatter italianDateFormatter
= DateTimeFormatter.ofPattern("dd/MM/uuuu");
21/01/2019
What’s wrong with using XMLGregorianCalendar?
When you call System.out.println(xmlDate), you are implicitly calling toString on your XMLGregorianCalendar. When it hasn’t got time and zone offset, toString always generates yyyy-MM-dd format, there is no way you can change that. On the other hand you can have any format you like in a String. Next obstacle is, there is no formatter that can format an XMLGregorianCalendar directly. You would need to convert to a different type, like ZonedDateTime, for example, first. Since you only want the date, neither the time of day nor the time zone, it’s simpler and easier to start out from LocalDate from the start. Not least for those reading and maintaining your code after you.
Your question mentions java.util.Date and your code uses GregorianCalendar too. Both of those classes are poorly designed and long outdated, fully replaced by java.time, the modern Java date and time API. So I suggest you don’t use them.
Link
Oracle tutorial: Date Time explaining how to use java.time, the modern Java date and time API.
This question already has answers here:
Unix epoch time to Java Date object
(7 answers)
Convert timestamp in milliseconds to string formatted time in Java
(10 answers)
Closed 5 years ago.
How to change milliseconds to Date object in yyyy-MM-dd HH:mm:ss format like 2017-04-12 23:14:52?
You cannot do that. For a couple of reasons.
TL;DR: Don’t use Date, use Instant. Neither of these can have a format in them. Formatting into a string is dependent on time zone, so you need to choose a time zone.
First, I understand from the discussion that you are asking for a java.util.Date object having the format yyyy-MM-dd HH:mm:ss. A Date object does not have and cannot have a format in it. The thing you should try to understand here is the difference between data itself and presentation of data to a user. An int may hold the value 25389, but it doesn’t hold it in the format 25389 (in fact the internal representation is quite different from 25389). The same int may be presented to a user as 25389, 000025389, 25,389 or +25389, just to mention a few out of many possibilities. The formatting happens outside the int while the int stays just the same.
Similarly, a Date object holds a point in time. The same date may be formatted into for example 2017-04-12 23:14:52 or April 12, 2017 11:14:52 PM. It may even be formatted for different time zones, which would be a good idea if the system has users in different time zones. Alternatively we may show the user a calendar leaf and/or a clock showing the time. Again, formatting happens outside of the Date while the Date stays just the same.
Elaborating on the time zone issue, the same point in time represented by the same millisecond value could be formatted to 2017-04-12 17:44:52 in UTC, 2017-04-12 19:44:52 in my time zone, 2017-04-12 23:14:52 in Asia/Kolkata time zone or even 2017-04-13 05:44:52 in Pacific/Auckland time zone. Note that in the last case not even the date is the same. So there is not just one way to change your milliseconds into the format you asked for. We need to know which time zone you want it for before we can help you.
So what I believe you need is not one thing, but two
A way to store your point in time in your program.
A way to format your point in time into a string in yyyy-MM-dd HH:mm:ss format for a user in some time zone.
For storing your point in time, use either of
A long for the milliseconds value you already have
A java.time.Instant object.
Why didn’t I mention java.util.Date? Because this class is long outdated. Its design turned out to be troublesome very quickly. They tried to repair it by deprecating most of the methods and introducing java.util.Calendar, but that didn’t work very well either. Finally, drawing on the experiences from a library known as Joda-Time they introduced the java.time classes in Java 8 in 2014. That’s three years ago as of writing, and counting. So IMHO we should by now have thrown Date and friends overboard and started using the newer classes. So prefer Instant over Date.
Changing your milliseconds to an Instant is straightforward:
long milliseconds = 1492019092000L;
Instant pointInTime = Instant.ofEpochMilli(milliseconds);
For formatting your instant into a string for the user, as I said, we require a time zone. Then do
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String formattedDateTimeString = pointInTime.atZone(ZoneId.of("Asia/Kolkata"))
.format(formatter);
So you need to fill in the desired time zone where I put ZoneId.of("Asia/Kolkata"). If you want to use the JVM’s current time zone setting, just fill in ZoneId.systemDefault(). Beware, though, that the time zone setting may be changed, even by an unrelated program running in the same JVM, so relying on this may be fragile.
The result of the above code snippet is a string like
2017-04-12 23:14:52
PS If after reading the above you really insist, here’s how to get a java.util.Date from the above:
Date myOutdatedDateInstance = Date.from(pointInTime);
(and excuse me for repeating, it still doesn’t have the desired format, that is not possible).
You can try this sample code.
public class MillDateConverter {
public static String dFormat = "yyy-MM-dd HH:mm:ss";
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dFormat);
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
long milliSec=Long.parseLong("1086073200000");
System.out.println(milliSec);
calendar.setTimeInMillis(milliSec);
System.out.println(simpleDateFormat.format(calendar.getTime()));
}
}
This question already has answers here:
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Closed 5 years ago.
I have a DateFormat like
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
I have a date like this:
2017-02-23T11:00:04.072625
This "date" is a UTC date (Z is null). This parses fine. However, it seems to be interpreted as the timezone of the machine. So, my machine is EST, this ends up as
2017-02-23T11:00:04.072625-0500
Which is wrong. I can explicitly set the timezone with like
format.setTimeZone(TimeZone.getTimeZone("UTC"));
But if the time came in a different zone in the future, that would not be right either.
If I add a "Z" or "z" to the SimpleDateFormat string, this fails to parse.
Any ideas on how to handle this correctly?
First, since you are using Java 8, start by discarding the old classes Date, DateFormat, SimpleDateFormat and TimeZone. They will more likely than not give you trouble you don’t want. Instead use the classes in java.time introduces in Java 8. Here you go:
String yourDateTime = "2017-02-23T11:00:04.072625";
LocalDateTime ldt = LocalDateTime.parse(yourDateTime);
Instant i = ldt.atOffset(ZoneOffset.UTC).toInstant();
Instant is the new class that best corresponds to the old Date. In this case you get
2017-02-23T11:00:04.072625Z
(Z means UTC)
If in the future you get the date in a different time zone, you may do something like
ZoneId zi = ZoneId.of("Europe/Paris");
Instant i = ldt.atZone(zi).toInstant();
In this case you get instead
2017-02-23T10:00:04.072625Z
Should you for some reason require an oldfashioned Date instance, for example for use with old code, it’s easy:
Date oldfashionedDate = Date.from(i);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I just started taking a computer science class a week ago, and I found this code to get the date and time. But I don't fully understand what everything in this means. If anyone could clarify that would be awesome! :)
long yourmilliseconds = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm");
Date resultdate = new Date(yourmilliseconds);
System.out.print("Date: ");
System.out.println(sdf.format(resultdate));
long yourmilliseconds = System.currentTimeMillis();
get the number of milliseconds from the System
Date resultdate = new Date(yourmilliseconds);
Creates a date from it. These two lines could be changed to
Date resultdate = new Date();
As dates in JDK1.7 and previous did not have any intrinsic formatting a formatting class is used
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm");
This is the pattern it will print as
System.out.println(sdf.format(resultdate));
Now we call the formatting method and print it out.
Scary Wombat did a good job explaining the individual steps to you, but there is a bit more to it.
First of all, learning programming is about making experiences yourself. So, your first step to approach this would be: take that source code, and instead of pasting it into a SO question ... paste it into a "public static void main" method; within a public class; compile it, run it, and see what happens. And start playing around with it.
If that leaves you with questions, the next step would be to lookup javadoc - you see; all your code deals with standard classes; and they are all well documented.
So, lesson for today: asking here is OK, but make sure that you really try to figure such things yourself first! Not only because the policy of this site says so, but because that gives you the most learning results out of your efforts!
java.time
That code:
Captures the current moment (date-time)
Generates a String to textually represent that moment.
Note that these are two distinct concepts. A date-time object is not a String. A date-time object generates a String to represent its value. Novice programmers often conflate the two causing much confusion and frustration.
Unfortunately that code snippet uses some old legacy date-time classes now supplanted by the java.time classes. The old classes have proven to be poorly designed, confusing, and troublesome.
The modern way to capture the current moment is simple. The Instant class represents a moment in the timeline in UTC with a resolution up to nanoseconds.
Instant instant = Instant.now();
To generate a String that represents that moment in standard ISO 8601 format, simply call toString.
String output = instant.toString();
2016-09-12T05:36:55Z
Adjust into a particular time zone (ZoneId) to see the same moment through the lens of that region’s wall-clock time.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Again, to generate a String that represents that moment in standard ISO 8601 format, simply call toString. Actually, the ZonedDateTime extends the standard by wisely appending the name of the time zone in square brackets.
String output = zdt.toString();
2016-09-12T01:36:55-04:00[America/Montreal]
To generate Strings in other formats, search Stack Overflow for the java.time class DateTimeFormatter.