I need to check if a given timestamp is today. I am using Joda-Time. Is there a method or a simple way to check this? What Joda-Time class is better suited for this? LocalDate? DateTime?
The date can be compared by single statement so why you need a special function.
when dateTimeis an object of DateTime()
if((dateTime.toLocalDate()).equals(new LocalDate()))
when date is an object of java.util.date
if((new DateTime(date).toLocalDate()).equals(new LocalDate()))
What Joda-time class is better suited for this? LocalDate? DateTime?
The understanding that you need to know what is LocalDate and DateTime.
LocalDate() is an immutable datetime class representing a date without a
time zone. So is not having a time part.
DateTime() is the standard implementation of an unmodifiable datetime
class. Its having all the attributes of the Date, which includes
date, time and timezone.
So if you need to compare both the date and time better go with datetime, if you just need to check the date you must use localDate because the datetime will produce a false if an .equal operator is used, unless the time including the seconds part are same for both the objects.
Here are some simple methods to check if a DateTime is today, tomorrow or yesterday:
public boolean isToday(DateTime time) {
return LocalDate.now().compareTo(new LocalDate(time)) == 0;
}
public boolean isTomorrow(DateTime time) {
return LocalDate.now().plusDays(1).compareTo(new LocalDate(time)) == 0;
}
public boolean isYesterday(DateTime time) {
return LocalDate.now().minusDays(1).compareTo(new LocalDate(time)) == 0;
}
One possibility is to create an interval covering the whole day in question, and then check if the various timestamps are contained in this interval.
Constructing the initial interval could look like:
Interval today = new Interval(DateTime.now().withTimeAtStartOfDay(), Days.ONE);
Then the timestamps could be checked like so:
today.contains(DateTime.now()); // True
today.contains(DateTime.now().minusDays(1)); // False
today.contains(DateTime.now().plusDays(1)); // False
today.contains(someOtherTimeStamp.toDateTime()); // And so on...
The recommended way to do this would be:
DateTime midnightToday = DateTime.now().withTimeAtStartOfDay();
DateTime myDateTime = <whatever>;
if(myDateTime.isAfter(midnightToday)) {
}
I think you need Joda 2.5 to do this, but that should do the trick.
I like #JustinMorris's answer. But I found this even better:
public static boolean isToday(DateTime time) {
return LocalDate.now().equals(new LocalDate(time));
}
public static boolean isTomorrow(DateTime time) {
return LocalDate.now().plusDays(1).equals(new LocalDate(time));
}
public static boolean isYesterday(DateTime time) {
return LocalDate.now().minusDays(1).equals(new LocalDate(time));
}
AFAIK there is no direct method available by which you can check the Date is Today Date or not.
The simplest approach will be constructing two DateTime one with the Timestamp, and another with today Date and then comparing day from dayOfYear() and year from year() but do remember whether both Date are in UTC or in Local Time Zone.
A small sample,
DateTime date = new DateTime(TimeStamp);
DateTime todayDate = new DateTime();
if(date.dayOfYear().get() == todayDate.dayOfYear().get() && date.year().get() == todayDate.year().get())
{
System.out.println("Date is today date");
}
Joda time actually have a method for this:
DateUtils#isToday(ReadablePartial);
DateUtils#isToday(ReadableInstant);
Simplest way I've found:
public boolean isToday(DateTime dateTime) {
return dateTime.withTimeAtStartOfDay().getMillis() ==
new DateTime().withTimeAtStartOfDay().getMillis();
}
Related
i all, i have a spring boot application. what i want in specific is to convert a class (that have nestet object field) in his corrispective entity. example:
public class example{
String string;
ObjectExample object;
}
public class ObjectExample{
String oneString;
XMLGregorianCalendar date;
}
this 2 object are also marked in another package as entities, but ovviusly in the ObjectExampleEntity i have Date date instead XMLGregorianCalendar, like this with the example
#Entity
public class example{
String string;
ObjectExample object;
}
#Entity
public class ObjectExample{
String oneString;
Date date;
}
because i have a big model and big entity (this above is only an example) with a lot of nested classes , i use dozer to convert from the model to the class.
consider for example that the repository jpa is only created for the father example class.
i want to know how i can with dozer convert from Date (entity) to XMLGregorianCalendar (model) and reverse. the model and the entity,i repeat are equal. the only difference is the type of the date. thanks
I am assuming:
Since your variable is named date it contains a calendar date (without time of day).
You are tied to XMLGregorianCalendar because of a WSDL outside your control, but you can change type on the entity side.
Based on these assumptions I recommend LocalDate on the entity side. It’s part of java.time, the modern Java date and time API, and represents exactly a date without time of day. The Date class that you used is poorly designed, long outdated and not recommended. Also despite the name a Date never represented a date, but a point in time.
There are more options. I am presenting three.
Option 1: transfer individual fields
From XMLGregorianCalendar to LocalDate:
DatatypeFactory xmlFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar wsDate = xmlFactory
.newXMLGregorianCalendarDate(2019, DatatypeConstants.MARCH, 30,
DatatypeConstants.FIELD_UNDEFINED);
// Validate
if ((wsDate.getHour() != 0 && wsDate.getHour() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMinute() != 0 && wsDate.getMinute() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getSecond() != 0 && wsDate.getSecond() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMillisecond() != 0 && wsDate.getMillisecond() != DatatypeConstants.FIELD_UNDEFINED)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (wsDate.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Convert
LocalDate entityDate = LocalDate.of(wsDate.getYear(), wsDate.getMonth(), wsDate.getDay());
System.out.println(entityDate);
The output is in this case:
2019-03-30
From LocalDate to XMLGregorianCalendar:
LocalDate entityDate = LocalDate.of(2019, Month.MARCH, 31);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendarDate(
entityDate.getYear(),
entityDate.getMonthValue(),
entityDate.getDayOfMonth(),
DatatypeConstants.FIELD_UNDEFINED);
System.out.println(wsDate);
2019-03-31
Advantage of this way: It’s pretty straightforward. Disadvantage: You and your reader need to take care that the fields are mentioned in the right order.
Option 2: convert via strings
// Validate as before
// Convert
LocalDate entityDate = LocalDate.parse(wsDate.toXMLFormat());
Result is as before.
XMLGregorianCalendar wsDate
= xmlFactory.newXMLGregorianCalendar(entityDate.toString());
Advantage: it’s brief, and there’s no surprise that the results are correct. Disadvantage: To me it feels like a waste to format into a string only to parse it back.
Option 3: convert via GregorianCalendar and ZonedDateTime
ZonedDateTime zdt = wsDate.toGregorianCalendar().toZonedDateTime();
// Validate
if (! zdt.toLocalTime().equals(LocalTime.MIN)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (! zdt.getZone().equals(ZoneId.systemDefault())) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Finish conversion
LocalDate entityDate = zdt.toLocalDate();
And the other way:
// It doesn’t matter which time zone we pick
// since we are discarding it after conversion anyway
ZonedDateTime zdt = entityDate.atStartOfDay(ZoneOffset.UTC);
GregorianCalendar gCal = GregorianCalendar.from(zdt);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendar(gCal);
wsDate.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
wsDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
The validation I present here is a bit simpler but also not quite so strict. If you want strict validation, you can just use the validation from before.
Advantages: I think it’s the official way; at least it uses the conversion methods offered. What I like is that the conversion itself is direct and brief. Disadvantage: When converting to XMLGregorianCalendar we need to set the unused fields to undefined manually, which makes it wordy.
Conclusion
I have presented three options each with their pros and cons. You may also mix, of course, but using a similar conversion both ways is probably less confusing in the end.
I am implementing toString methods for my entities. There are a lot of fields of type ZonedDateTime. Unfortunately, it's converted to extremely long text representation:
java.util.GregorianCalendar[
time=1545826815293,
areFieldsSet=true,
areAllFieldsSet=true,
lenient=true,
zone=sun.util.calendar.ZoneInfo
[
id=
"UTC",
offset=0,
dstSavings=0,
useDaylight=false,
transitions=0,
lastRule=null
],
firstDayOfWeek=1,
minimalDaysInFirstWeek=1,
ERA=1,
YEAR=2018,
MONTH=11,
WEEK_OF_YEAR=52,
WEEK_OF_MONTH=5,
DAY_OF_MONTH=26,
DAY_OF_YEAR=360,
DAY_OF_WEEK=4,
DAY_OF_WEEK_IN_MONTH=4,
AM_PM=1,
HOUR=0,
HOUR_OF_DAY=12,
MINUTE=20,
SECOND=15,
MILLISECOND=293,
ZONE_OFFSET=0,
DST_OFFSET=0
]
How can I format it using SimpleDateFormat?
I tried the example given here:
https://howtodoinjava.com/apache-commons/how-to-override-tostring-effectively-with-tostringbuilder/
public class CustomToStringStyle extends ToStringStyle
{
private static final long serialVersionUID = 1L;
protected void appendDetail(StringBuffer buffer, String fieldName, Object value)
{
if (value instanceof Date)
{
value = new SimpleDateFormat("yyyy-MM-dd").format(value);
}
buffer.append(value);
}
}
But in this case, I don't use JSON style of formatting. I can't extend JsonToStringStyle because it's private.
ZonedDateTime is part of the new Java 8 API while SimpleDateFormat is the old buggy Date formatter. You need to use the new DateFormatter for Java 8 date/time classes.
The JSON you posted however is neither a ZonedDateTime, nor a Date, it is a GregorianCalendar, so not sure whether your problem is really to do with ZonedDateTime as you are saying.
GregorianCalendar is not Date, you can convert it to Date, then use the code in your link:
if (value instanceof calendar)
{
Date date = new Date(value.getTimeInMillis());
value = new SimpleDateFormat("yyyy-MM-dd").format(date);
}
I would suggest to use java.time package to deal with date and time.
Recently there is a process we’re working on taking a lot more memory than expected. Upon checking the heap there are a lot of java.util.LocalTime created. Which can be explained because we do store some data in a timemap with LocalTime as key. Probably there is too much of that data generated from upstream compared to the expected.
However, there is a surprise that also a lot of sun.util.calendar.ZoneInfo are created. We don't use this class; will it generated by LocalTime? But if we check the source code of java.time.LocalTime, I don't see ZoneInfo is used; does anyone have an idea about that?
Sorry for late answer but now I have found some time to inspect the JDK-sources.
If you call LocalTime.now() then java.time will use the system timezone (an implicit dependency).
public static LocalTime now() {
return now(Clock.systemDefaultZone());
}
And then Clock loads ZoneId.systemDefault():
public static Clock systemDefaultZone() {
return new SystemClock(ZoneId.systemDefault());
}
Finally, the class java.util.TimeZone is used to find the default zone.
public static ZoneId systemDefault() {
return TimeZone.getDefault().toZoneId();
}
And if you look into the source of TimeZone.getDefault() then you will see at some depth down the stack:
private static TimeZone getTimeZone(String ID, boolean fallback) {
TimeZone tz = ZoneInfo.getTimeZone(ID);
if (tz == null) {
tz = parseCustomTimeZone(ID);
if (tz == null && fallback) {
tz = new ZoneInfo(GMT_ID, 0);
}
}
return tz;
}
Voilá, the class sun.util.calendar.ZoneInfo will be loaded, too.
I have a parametrized method:
private static Date getTimeFor(int hour, int minute, int second, int nanoSecond, String zoneId) {
ZonedDateTime time = ZonedDateTime.now()
.withZoneSameLocal(ZoneId.of(zoneId))
.withHour(hour)
.withMinute(minute)
.withSecond(second)
.withNano(nanoSecond);
return Date.from(time.toInstant());
}
Followed by:
private Date getRomeStartTime(){
return getTimeFor(8,30,0,0,"Europe/Rome");
}
private Date getParisStartTime(){
return getTimeFor(9,30,0,0,"Europe/Paris");
}
private Date getLondonStartTime(){
return getTimeFor(9,00,0,0,"Europe/London");
}
This can get out of hand quickly as more cities are added. I'm aiming to only make public/expose the below method and delegate the construction of StartTimes elsewhere:
public Date getEffectiveTimeFor(String zoneId){
// Delegate construction as per zoneId elsewhere
// dont want to use a long-winded if-else statement
}
I cant use the strategy pattern as I should not pass an object, but only a string.
What is the best approach here?
(p.s. I have to return the old Date, this is beyond the question )
You can simply use a Map<String, LocalTime> to store the start time for each zone ID. Then get the start time from this map in your method and create the Date from there.
I have this code copied from one of questions from SO:
public static String getCurrentTimeStamp() {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String strDate = sdfDate.format(now);
return strDate;
}
I want to get only the system time and NOT the date. Then I must change second line of code to:
SimpleDateFormat sdfDate = new SimpleDateFormat(" HH:mm:ss") ;
Then, DATE() must get the current time. Clear upto this point but I can't understand the format() function used.
I mean cant we simply output variable now instead of strdate?
Is it just because that the return type of function getCurrentTimeStamp() is String?
Please clarify and if there is any other simpler and one line code for getting system time alone, do share.
I mean cant we simply output variable now instead of strdate.
Well you could return now.toString() - but that will use the format that Date.toString() happens to choose, whereas you want a specific format. The point of the SimpleDateFormat object in this case is to convert a Date (which is a point in time, without reference to any particular calendar or time zone) into a String, applying an appropriate time zone, calendar system, and text format (in your case HH:mm:ss).
You can still simplify your method somewhat though, by removing the local variables (which are each only used once):
public static String getCurrentTimeStamp() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
Or maybe you'd find it more readable to keep the variable for the date format, but not the date and the return value:
public static String getCurrentTimeStamp() {
DateFormat format = new SimpleDateFormat("HH:mm:ss");
return format.format(new Date());
}
Personally I'd recommend using Joda Time instead, mind you - it's a much nicer date/time API, and its formatted are thread-safe so you could easily keep a reference to a single formatting object.
public static String getCurrentTimeStampwithTimeOnly() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
Helps you to do this.
you can call this line any time
Date now = new Date();
The now variable will contain the current timestamp
The format function just generates a String from this timestamp
also take a look at the Calendar class ( Calendar.getInstance())