I want to compare two date type only date not time.
date1 = 2022.10.10 16:30:40
date2 = 2022.10.10 13:30:40
these dates are same date so I want to return true.
below is my code. is there clean code?
public Boolean a0160(HashMap<String, Object> params){
Date accessRecord;
Date now = new Date();
accessRecord = userMapper.a0170(params);
Calendar calAccessRecord = Calendar.getInstance();
Calendar calOneHourBefore = Calendar.getInstance();
calAccessRecord.setTime(accessRecord);
calOneHourBefore.setTime(now);
calOneHourBefore.add(Calendar.HOUR, -1);
int calOneHourBeforeYear = calOneHourBefore.get(Calendar.YEAR);
int calOneHourBeforeMonth = calOneHourBefore.get(Calendar.MONTH);
int calOneHourBeforeDate = calOneHourBefore.get(Calendar.DATE);
int calAccessRecordYear = calAccessRecord.get(Calendar.YEAR);
int calAccessRecordMonth = calAccessRecord.get(Calendar.MONTH);
int calAccessRecordDate = calAccessRecord.get(Calendar.DATE);
if(calOneHourBeforeYear == calAccessRecordYear && calAccessRecordMonth == calOneHourBeforeMonth && calAccessRecordDate == calOneHourBeforeDate){
return true;
} else {
return false;
}
}
tl;dr
myJavaUtilDate
.toInstant()
.atZone(
ZoneId.of( "Pacific/Auckland" )
)
.toLocalDate()
.isEqual(
ZonedDateTime
.now( ZoneId.of( "Pacific/Auckland" ) )
.minusHours( 1 )
.toLocalDate()
)
java.time
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Apparently you are handed a java.util.Date object. The first thing to do is convert from the flawed legacy to its modern replacement, java.time.Instant. Use new conversion methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
Both the legacy and modern classes represent a moment as seen with an offset from UTC of zero hours-minutes-seconds.
Understand that for any given moment, the date varies around the globe by time zone. So determining a date requires the context of a time zone.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the date portion.
LocalDate ld = zdt.toLocalDate() ;
Apparently you want to compare that to the current date as of one hour ago.
LocalDate dateAnHourAgo = ZonedDateTime.now( z ).minusHours( 1 ).toLocalDate() ;
Compare with isEqual, isBefore, and isAfter methods.
They aren't dates; they're strings:
return date2.startsWith(date1.substring(0, 10));
Related
I can get the current date using
Instant.now()
I am looking to get 18-<current month>-<current year>
I endorse Basil Bourque's answer. However, if you are looking for an Instant object, you can get it by adjusting the current OffsetDateTime at UTC to 18th day of the month as shown below:
public class Main {
public static void main(String[] args) {
Instant thisInstantOn18th = OffsetDateTime.now(ZoneOffset.UTC)
.with(ChronoField.DAY_OF_MONTH, 18)
.toInstant();
System.out.println(thisInstantOn18th);
}
}
Output:
2022-12-18T19:19:20.128313Z
Learn more about the modern Date-Time API from Trail: Date Time.
tl;dr
YearMonth // Represents a year and month only, no day of month.
.now(
ZoneId.of( "America/Edmonton" ) // Returns a `ZoneId` object.
)
.atDay( 18 ) // Returns a `LocalDate` object.
.format(
DateTimeFormatter
.ofPattern( "dd-MM-uuuu" )
) // Returns a `String` object.
Details
As Comments by Ole V.V. explain, you are using the wrong class. No need for Instant here.
To represent a date, use LocalDate.
To represent a year and month, use YearMonth.
Capture the current year-month.
Doing so requires a time zone. For any given moment, the date varies around the globe by time zone. So the current month could be simultaneously “next month” in Tokyo Japan while “last month” in Toledo Ohio.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
YearMonth ym = YearMonth.now( z ) ;
If you want the current month as seen with an offset of zero hours-minutes-seconds from UTC, use ZoneOffset.UTC constant.
YearMonth ym = YearMonth.now( ZoneOffset.UTC ) ;
Apply a day of month to get a date.
LocalDate ld = ym.atDay( 18 ) ;
Generate text in standard ISO 8601 format.
String output = ld.toString() ;
Generate text in a specific format.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ;
String output = ld.format( f ) ;
I'm trying to compare dates as i take input from user using date in html and send it to servlet to validate it or know if it's today's date this is my trial and it would only work with two digit months as it prints month as 5 not 05
String date = request.getParameter("birth");
Date d = new Date();
Calendar calendar = new GregorianCalendar();
calendar.setTime(d);
int year = calendar.get(Calendar.YEAR);
int month = calender.get(Calendar.MONTH);
month+=1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
String dat = (Integer.toString(year)+"-"+Integer.toString(month)+"-"+Integer.toString(day));
PrintWriter out = response.getWriter();
if(dat.equals(date))
out.println("Today");
}}
i feel like the code just looks so sad.
tl;dr
LocalDate
.parse(
"2022-05-24"
)
.isEqual(
LocalDate
.now(
ZoneId.of( "America/Edmonton" )
)
)
Avoid legacy classes
Do not use Calendar, Date, SimpleDateFormat classes. These terrible classes were years ago supplanted by the modern java.time classes defined in JSR 310.
Compare objects, not text
Do not compare dates as text. Compare objects instead.
LocalDate
Parse your textual input into a LocalDate if you are working with date-only, without time of day, and without time zone.
ISO 8601
Apparently your input string is in standard ISO 8601 format, YYYY-MM-DD. If so, no need to specify a formatting pattern.
String input = "2022-05-24" ;
LocalDate ld = LocalDate.parse( input ) ;
Capture the current date. Time zone is crucial here. For example, at the same simultaneous moment it can be tomorrow in Tokyo Japan while yesterday in Toledo Ohio US.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate#isEqual
Compare.
boolean isToday = ld.isEqual( today ) ;
All this has been covered many times already on Stack Overflow. Search to learn more.
you could just add zero when month is < 10 :
for example:
if(month < 10)
String dat = (Integer.toString(year)+"-0"+Integer.toString(month)+"-"+Integer.toString(day));
else
String dat = (Integer.toString(year)+"-"+Integer.toString(month)+"-"+Integer.toString(day));
I want to get the UTC instant (since my DB is storing in UTC) from Java (which is also in UTC) of a particular time zone, this is what I have tried so far:
public static Instant getStartOfTheDayDateTime(Instant instant, String zoneId) {
ZonedDateTime zoned = instant.atZone(ZONE_ID_TO_ZONE_MAP.get(zoneId));
ZoneId zone = ZoneId.of(zoneId);
return zoned.toLocalDate().atStartOfDay(zone).toInstant();
// ZonedDateTime startOfTheDay = zoned.withHour(0)
// .withMinute(0)
// .withSecond(0)
// .withNano(0);
//
// return startOfTheDay.toInstant();
}
public static Instant getEndOfTheDayDateTime(Instant instant, String zoneId) {
ZonedDateTime zoned = instant.atZone(ZONE_ID_TO_ZONE_MAP.get(zoneId));
ZonedDateTime endOfTheDay = zoned.withHour(0)
.withMinute(0)
.withSecond(0)
.withNano(0)
.plusDays(1);
return endOfTheDay.toInstant();
}
Every attempt shows:
2020-04-10 22:00:00.0(Timestamp), 2020-04-11 22:00:00.0(Timestamp)
Is this the start/end of the day UTC time in Europe/Paris zone ?
I was expecting to have 2020-04-11 02:00:00.0(Timestamp), 2020-04-12 02:00:00.0(Timestamp)
Right now, Paris is on summer time: UTC+2. Paris is 'ahead' of UTC by 2 hours.
So 00:00:00 in Paris local time is 22:00:00 UTC.
Is this the start/end of the day UTC time in Europe/Paris zone ?
Yes. Europe/Paris is in daylight savings time. Midnight in Paris occurred at 22:00 UTC time.
I was expecting to have 2020-04-11 02:00:00.0(Timestamp), 2020-04-12 02:00:00.0(Timestamp)
That's not right, 02:00 UTC would have been 04:00 in Paris time.
Ask programmatically if a moment is in DST
Is this the start/end of the day UTC time in Europe/Paris zone ?
Get start of day.
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtStartOfDay = instant.atZone( z ).toLocalDate().atStartOfDay( z ) ;
Ask if that moment is in DST for that zone.
ZoneRules rules = z.getRules();
boolean isDst = rules.isDaylightSavings( zdtStartOfDay.toInstant() );
Pass date-time objects rather than mere strings
public static Instant getStartOfTheDayDateTime(Instant instant, String zoneId)
I suggest you ask the calling programmer to pass a valid ZoneId object rather than a mere string. It should not be the job of this method to validate their string input. If it is reasonable to expect a Instant then it is also reasonable to expect a ZoneId.
public static Instant getStartOfTheDayDateTime(Instant instant, ZoneID zoneId )
Half-Open
public static Instant getEndOfTheDayDateTime(Instant instant, String zoneId) {
Trying to determine the last moment of the day is impossible because of infinitely divisible last second.
Also this approach to defining a span of time is awkward. It makes abutting multiple spans tricky. Various software systems and protocols differ in their resolution of that last fractional second, using milliseconds, microseconds, nanoseconds, or some other fraction.
The common practice in date-time handling is to track a span of time using the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive.
So a full day begins with the first moment of the day and runs up to, but does not include, the first moment of the next day.
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtStartOfDay = instant.atZone( z ).toLocalDate().atStartOfDay( z ) ;
ZonedDateTime zdtStartOfNextDay = instant.atZone( z ).toLocalDate().plusDays( 1 ).atStartOfDay( z ) ;
You might want to break that code out to more lines, for easier reading/debugging.
Instant instant = Instant.now() ; // Or passed in.
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDate ld = zdt.toLocalDate() ;
LocalDate ldNextDay = ld.plusDays( 1 ) ;
ZonedDateTime zdtStartOfNextDay = ldNextDay.atStartOfDay( z ) ;
See this code run live at IdeOne.com. For example:
System.out.println( instant ) ; // 2020-04-13T00:15:25.235341Z
System.out.println( zdt ) ; // 2020-04-13T02:15:25.235341+02:00[Europe/Paris]
System.out.println( ld ) ; // 2020-04-13
System.out.println( ldNextDay ) ; // 2020-04-14
System.out.println( zdtStartOfNextDay ) ; // 2020-04-14T00:00+02:00[Europe/Paris]
ThreeTen-Extra Interval
If you do this kind of work with spans of time often, then I suggest adding the ThreeTen-Extra library to your project. That library includes the Interval class to track a span-of-time as a a pair of Instant objects.
Interval interval = Interval.of( zdtStartOfDay.toInstant() , zdtStartOfNextDay.toInstant() ) ;
You can then make use the several handy comparison methods such as abuts, contains, encloses, intersection, overlaps, and union.
Timestamp
Never use the java.sql.Timestamp class. This class is part of the terrible date-time classes that shipped with the earliest versions of Java. These classes are now legacy, supplanted entirely by the modern java.time classes defined in JSR 310 and built into Java 8 and later.
As of JDBC 4.2 we can exchange java.time objects with a database. Use getObject and setObject and updateObject.
The JDBC spec oddly requires support for OffsetDateTime but not the more commonly used Instant and ZonedDateTime. Your particular driver may support these other types. If not, convert.
Retrieval from database.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
Sending to the database.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
I need to pass in a Date object into a service which my API is calling. I have the info on the day, month, and year for the Date but also need a timestamp. The service is expecting it in this format:
<date>2015-04-01T00:00:00-05:00</date>
How can I add something to the Date to get this format?
Never use java.util.Date. Supplanted by java.time.Instant.
Get your date portion.
LocalDate ld = LocalDate.of( 2015 , 4 , 1 ) ;
Or use the readable Month enum.
LocalDate ld = LocalDate.of( 2015 , Month.APRIL , 1 ) ;
Get the time of day when the day starts in some particular time zone. Do not assume the day starts at 00:00:00, may be some other time such as 01:00:00. Let java.time figure that out for you.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
Generate a string in your desired format, a standard ISO 8601 format.
DateTimeFormatter f = DateTimeFormatter.ISO_OFFSET_DATE_TIME ;
String output = zdt.format( f ) ;
To see that moment in UTC, extract a Instant.
Instant instant = zdt.toInstant() ;
Conversion
If you must inter-operate with old code not yet updated for java.time, you can call new conversion methods added to the old classes. These include Date::from( Instant ).
java.util.Date d = java.util.Date.from( instant ) ;
Going the other direction.
Instant instant = d.toInstant() ;
Get back to a time zone other than UTC.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ; // Same moment, different wall-clock time.
Working with dates in Java is an ugly mess, always has been. Date class is mostly deprecated now. I am using LocalDateTime where you can construct it by calling year, month, day, hour, minute, and seconds. Here is what I could come up with:
LocalDateTime ldt = LocalDateTime.of(1997, Month.SEPTEMBER, 2, 1, 23, 0);
ZonedDateTime systemTime = ldt.atZone(ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME; //Basil's idea
System.out.println(systemTime.format(formatter));
Output:
1997-09-02T01:23:00-05:00
You could use SimpleDateFormat for this.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
dateFormat.format(new Date());
I am currently reading dates in JSON format as follows:
"dates": {
"startdate": "2017-08-29T22:00:00.000UTC";
}
And in my application, I set the JsonFormat as follows to be able to read it correctly:
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'UTC'")
private Date startdate;
But UTC isn't the TimeZone I want to work with, what should I change 'UTC' into to be able to read my dateTime in the Europe/Paris zone?
Alter the input to comply with the ISO 8601 standard. The Z is short for Zulu and means UTC.
String input = "2017-08-29T22:00:00.000UTC".replace( "UTC" , "Z" ) ;
Parse as an Instant object.
Instant instant = Instant.parse( input ) ;
Adjust into your desired time zone.
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Avoid the Date class as that troublesome class is now legacy, supplanted by the java.time classes.