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 8 months ago.
Improve this question
I have a date say 2022-07-10 as date (YYY/MM/dd) and time as 00:15
ie. 202207**10*****0015***
after subtracting 30 mins from above the result must be
2022-07-09 and time as 23:45
ie. 202207**09***2345***
other scenarios:
202207100030 -->202207100000
202207100010 -->202207092340
202207100035 -->202207100005
Could you please help me out with this.
What you want doesn't make sense. 2022-07-10 00:15 minus 30 minutes? That's not 2022-07-09 23:45. Not neccessarily, anyway. Maybe a timezone shift means it's 2022-07-10 00:45 (but, before the timezone change). Or it's 2022-07-09 22:45. Or perhaps it's 2022-07-01 23:45 - it's been a good long while but a locale can skip a day (last time: When one of the islands in the pacific decided to hop across the date line), or even half a month (last time: Russian revolution. It's still in the 1900s).
You can't 'do' date-diff math on Local date/time concepts; a time zone is required.
Once you've established one this is trivial:
First, parse whatever you have into a LocalDate, LocalDateTime, OffsetDateTime, Instant, or ZonedDateTime object. These are all fundamentally different concepts - a key part of doing any time-based anything is figuring out what concept you're dealing with. For example, you seem to believe you're dealing with local date/times (no timezone), and yet also with a concept that can 'do' date diff math (which is mutually exclusive, hence, some more analysis of the situation is required).
Then, transform what you have into the date/time concept you need to do the operation.
Do the operation.
Transform some more if needed.
format it back to a string if you want.
If you try to shortcut and skip steps, it'll work, until it doesn't. Because date/time is just that hard.
For example:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMM**dd*****HHmm***");
LocalDateTime ldt = LocalDateTime.parse("202207**10*****0015***", dtf);
This is a good start; you now have an LDT object with the right year, month, day, minute, and hour.
Let's localize it somewhere and do the math:
ZonedDateTime zdt = ldt.atZone(ZoneId.of("Europe/Amsterdam"));
zdt = zdt.minusMinutes(30);
System.out.println(zdt.format(dtf));
Prints 202207**09*****2345***; I assume that's what you want.
You need to use LocalDateTime.minus method:
DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime d = LocalDateTime.parse("2022-07-10 00:10", DATEFORMATTER);
d.atZone(ZoneId.systemDefault());
LocalDateTime d2 = d.minus(Duration.ofMinutes(30));
LocalDateTime d3 = d.minus(30, ChronoUnit.MINUTES);
System.out.println(d2); //2022-07-09T23:40
System.out.println(d3); //2022-07-09T23:40
Related
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 11 months ago.
This post was edited and submitted for review 11 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
Code
Date dates = new Date(Long.MAX_VALUE);
output -
292278994-08-17 12:42:55
I want to get the largest date today onwards. How to get this using another way.292278994 this year cant save my DB I need only 4 characters for the year.
To get the boundary dates of the current year, you can use the java.time API and set the month/day values to january 1st and december 31st respectively:
LocalDateTime now = LocalDateTime.now();
LocalDateTime startOfYear = now.withMonth(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime endOfYear = now.withMonth(12).withDayOfMonth(31).withHour(23).withMinute(59).withSecond(59).withNano(999999999);
System.out.println(startOfYear);
System.out.println(endOfYear);
Output:
2022-01-01T00:00
2022-12-31T23:59:59.999999999
Epoch milliseconds are milliseconds counted from the very first moment of 1970 and they are stored as long in Java. That means Long.MAX_VALUE will get you the moment in time that is as far in the future as this representation allows. A moment that is beyond some maximum date of the current year, like some hundred million years beyond…
If you are on Java 8 or higher and try to use an Instant with Long.MAX_VALUE like this:
public static void main(String[] args) {
// use the greates Long as epoch millis and create an Instant from it
Instant instant = Instant.ofEpochMilli(Long.MAX_VALUE);
// represent the Instant as date and time of day in a specific zone
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
// define the output format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
// and print the
System.out.println(zdt.format(dtf));
}
You will get the following output:
+292278994-08-17 07:12:55
You may want to adjust the ZoneId to the desired one and remove the leading plus from the output…
But basically understand that epoch milliseconds are not years.
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 1 year ago.
Improve this question
how to convert ISO_LOCAL_DATE to date time format : yyyy-MM-dd'T'HH:mm:ss.SSSZ in java
Ex: given date: 2016-01-25 to 2016-01-25T00:00:00.000+0100
I am assuming that have got a string, for example 2016-01-25, and that you want a string containing the start of the day in the JVM’s default time zone (it wasn’t clear from the question). I first define a formatter for the format that you want (it’s ISO 8601):
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
Now your conversion goes:
String isoLocalDateString = "2016-01-25";
LocalDate date = LocalDate.parse(isoLocalDateString);
ZonedDateTime dateTime = date.atStartOfDay(ZoneId.systemDefault());
String dateTimeString = dateTime.format(formatter);
System.out.println(dateTimeString);
When running in my time zone, Europe/Copenhagen, output from this example code is what you asked for:
2016-01-25T00:00:00.000+0100
In rare cases where summer time (DST) begins at the first moment of the day, the time of day will not be 00:00:00.000.
For parsing with ISO_LOCAL_DATE we don’t need to specify the formatter since this formatter is the default for LocalDate.parse().
All of this said, you should not normally want to convert a date from one string format to another string format. Inside your program keep dates as LocalDate objects. When you get string input, parse into a LocalDate. Only when you need to give string output, for example in data exchange with another system, format into a string in the required format.
Link: Wikipedia article: ISO 8601
There are various methods on LocalDate for this, including:
LocalDate::toDateTimeAtCurrentTime()
LocalDate::toDateTimeAtStartOfDay()
LocalDate::toDateTime( LocalTime )
LocalDate::toDateTime( LocalTime , DateTimeZone )
It is as simple as LocalDateTime localDateTime = yourLocalDate.atStartOfDay()
Update
Adding timestamp is as simple as:
ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime = zdt = localDateTime.atZone(zoneId);
Can be put together as
ZonedDateTime zdt = yourLocalDate.atStartOfDay().atZone(ZoneId.of("America/New_York"));
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
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 4 years ago.
Improve this question
I'm a bit baffled what format these timestamps are in. I was told the format to use is yyyy-MM-dd.HH:mm:ss but all of the timestamps appear like this 2017-01-01 00:08:57.231, 2017-01-01 07:43:36.348, or 2017-01-01 13:25:55.683. I'm not understanding why there are four sections to the time ?:Hour:Minute:Second in the actual data I have when the format I'm supposed to be using only has three time sections. Are these datetime timestamps not actually in the format of yyyy-MM-dd.HH:mm:ss?
No, your suspicion is correct, your example date-time strings are not in the format yyyy-MM-dd.HH:mm:ss. The dot between dd and HH must be a simple mistake, it should be a space since there is a space between date and time in the timestamp strings. Furthermore all of your example strings include milliseconds: in 00:08:57.231 you’ve got 57 seconds and 231 milliseconds, or if you like, 57.231 seconds, so the last section may also be referred to as fraction of second.
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
String timestampString = "2017-01-01 00:08:57.231";
LocalDateTime dateTime = LocalDateTime.parse(timestampString, formatter);
System.out.println(dateTime);
Output:
2017-01-01T00:08:57.231
For the nerdily curious: It is possible to parse the string, or more precisely most of it, with the format you had been given, only correcting the dot into a space:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String timestampString = "2017-01-01 00:08:57.231";
LocalDateTime dateTime = LocalDateTime.from(
formatter.parse(timestampString, new ParsePosition(0)));
In this case the result comes without the milliseconds:
2017-01-01T00:08:57
I see no reason why you should want this, though.
Avoid SimpleDateFormat
In a comment you gave a snippet that uses the SimpleDateFormat class. This class is not only long outdated, it is also notoriously troublesome. I see no reason why you should want to use it. Instead I am using java.time, the modern Java date and time API. In my experience it is so much nicer to work with.
Links
Oracle tutorial: Date Time explaining how to use java.time. You may especially want to study the section Parsing and Formatting.
These time stamps are in yyyy-MM-dd HH:mm:ss:ms format, last three digits are milliseconds.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed last month.
Improve this question
I'm building a simple organizer app and trying to pick a class to keep my date and time in object. Which classes should I use? I've seen that lots of methods in Date class are deprecated. Maybe Calendar then? Recommend something. Thanks.
It will depend on what kind of date / time you want.
System.currentTimeMillis() - this will give you a simple numeric value expressed as the number of miliseconds after the UNIX epoch as a long.
If you want year, month day format you could use one of these:
new Date() - this will give you a Date object initialized with current date / time. This is deprecated as the API methods are mostly flawed.
new org.joda.time.DateTime() - this will give you a joda-time object
initialized with the current date / time. Joda-time includes a great API for doing anything involving time point an duration calculations. With Java 8, however, this is no longer true
Calendar.getInstance() - this gives you a Calendar object initialized witht he current date / time, using the default locale and TimeZone.
If you just need a simple way to output a time stamp in format YYYY.MM.DD-HH.MM.SS - a very frequent case - then use this:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
Instant - if you want to do any work with business logic and data storage/exchange it should be done in UTC, as a best practice. To get the current moment in nanoseconds use the Instant class:
Instant instant = Instant.now();
You can also adjust that Instant into other time zones. Apply a ZoneId object to get a ZonedDateTime.
ZoneId zid = ZoneId.of("Europe/Paris"); //create zone id
ZonedDateTime zdt = instant.atZone(zid); //pass zone id get the adjusted zoned date time.
LocalDate - this class represents a date-only value without time-of-day and without time zone.
ZoneId zid = ZoneId.of("Europe/Paris");
LocalDate today = LocalDate.now(zid); //Always pass in a time zone