Creating a GregorianCalendar instance from milliseconds - java

I have a certain time in milliseconds (in a Timestamp object) and I want to use it to create a GregorianCalendar object. How can I do that?
EDIT: How do I do the reverse?

To get a GregorianCalendar object and not a Calendar object. Like Michael's answer provides, you can also do the following:
long timestamp = 1234567890;
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(timestamp);
This assumes a UTC epoch timestamp.

Just get an instance of GregorianCalendar and setTime with your java.sql.Timestamp timestamp:
Calendar cal=GregorianCalendar.getInstance();
cal.setTime(timestamp);
Edit:
As peterh pointed out, GregorianCalendar.getInstance() will not provide a GregorianCalendar by default, because it is inherited fromCalendar.getInstance(), which can provide for example a BuddhistCalendar on some installations. To be sure to use a GregorianCalender use new GregorianCalendar() instead.

Timestamp timestamp = new Timestamp(23423434);
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTimeInMillis(timestamp.getTime());

I believe this works, although it may not be the best approach:
import java.sql.Date;
import java.sql.Timestamp;
import java.util.GregorianCalendar;
public class TimestampToGregorianCalendar {
/**
* #param args
*/
public static void main(String[] args) {
Timestamp t = new Timestamp(12356342); // replace with existing timestamp
Date d = new Date(t.getTime());
Calendar gregorianCalendar = GregorianCalendar.getInstance();
gregorianCalendar.setTime(d);
}
}

Related

How get only year with type XMLGregorianCalendar

i have a XML Jaxb class to set with XMLGregorianCalendar type. But we are supposed to set only year in this attribute.
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(new
GregorianCalendar());
xmlCal.setYear(2021);
xmlObject.setBuiltYear(xmlCal);
// xmlCal.getYear() will give me year but its type int , so setter method not accepting it. If
has to be of type XMLGregorianCalendar only with year.
If i set it like above its giving 2021-09-23T10:19:38.346-04:00 but i need only year with type XMLGregorianCalendar . how we can do that ?
Use XMLGregorianCalendar#clear before setting the year.
Demo:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class Main {
public static void main(String[] args) throws DatatypeConfigurationException {
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar());
xmlCal.clear();
xmlCal.setYear(2021);
System.out.println(xmlCal);
}
}
Output:
2021
ONLINE DEMO
The answer by Arvind Kumar Avinash is good and correct. There are other ways to obtain the same, so as a supplement I am presenting a couple.
Edit: A simpler and shorter variant of the code by Arvind Kumar Avinash:
XMLGregorianCalendar xmlCal
= DatatypeFactory.newInstance().newXMLGregorianCalendar();
xmlCal.setYear(2021);
System.out.println(xmlCal);
Output:
2021
The no-arg newXMLGregorianCalendar() gives us an XMLGregorianCalendar with all fields undefined or null. Set the year, and we’re done.
You may also create your desired XMLGregorianCalendar fully complete directly from a factory method call. Here’s a longish variant:
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance()
.newXMLGregorianCalendarDate(2021, DatatypeConstants.FIELD_UNDEFINED,
DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
The result is the same as before. The fields that I set undefined are month, day of month and UTC offset (called timezone with XMLGregorianCalendar).
A much shorter variant is:
XMLGregorianCalendar xmlCal
= DatatypeFactory.newInstance().newXMLGregorianCalendar("2021");
Output is still the desired:
2021
Just as you want an XMLGregorianCalendar for the purpose of producing a specific string, the XMLGregorianCalendar can also be constructed from the string you want.
In case you had your year in an int, you may convert first:
int year = 2021;
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(String.valueOf(year));
It may feel like a waste to convert your int to a String only to have it parsed again. You decide.
Which way to prefer? It’s a matter of taste.
java.time.Year
As an aside, only if your class requires an XMLGregorianCalendar, use that class. For all other purposes I recommend the Year class:
Year year = Year.of(2021);
System.out.println(year);
2021

Sort Array object by date of its field

I have an Object MyTimes and in that object there are fields name ,start_date and configuration.
I have an array of this object, MyTimes [] mytimes
I am trying to sort the array by the start time but am struggling how to go about it.
The start_time field is a string, so this needs converting to a datetime.
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
for(int i=0; i<mytimes.length; i++) {
Date date = formatter.parse(mytimes[i].getStartTime());
}
I'd then put the date into an array list perhaps and then sort by datetime? But then I wouldnt know which start_time corresponds with which mytimes object...
What is the most efficient way of doing this?
Under the right circumstances this is a one-liner:
Arrays.sort(myTimes, Comparator.comparing(MyTimes::getStartDate));
Let’s see it in action:
MyTimes[] myTimes = {
new MyTimes("Polly", "2019-03-06T17:00:00Z"),
new MyTimes("Margaret", "2019-03-08T09:00:00Z"),
new MyTimes("Jane", "2019-03-01T06:00:00Z")
};
Arrays.sort(myTimes, Comparator.comparing(MyTimes::getStartDate));
Arrays.stream(myTimes).forEach(System.out::println);
Output:
Jane 2019-03-01T06:00:00Z
Polly 2019-03-06T17:00:00Z
Margaret 2019-03-08T09:00:00Z
I am assuming that getStartDate returns an Instant or another type the natural order of which agrees with the chronological order you want. For example:
public class MyTimes {
private String name;
private Instant startDate;
// Constructor, getters, toString, etc.
}
If you are receiving your start dates as strings somehow, you may write a convenient constructor that accepts a string for start date. I am already using such a constructor in the above snippet. One possibility is having two constructors:
public MyTimes(String name, Instant startDate) {
this.name = name;
this.startDate = startDate;
}
public MyTimes(String name, String startDate) {
this(name, Instant.parse(startDate));
}
The Instant class is part of java.time, the modern Java date and time API.
I am exploiting the fact that your strings are in the ISO 8601 format for an instant, the format that Instant.parse accepts and parses.
Avoid SimpleDateFormat and Date
I recommend you don’t use SimpleDateFormat and Date. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. There is also an error in your format pattern string for parsing: Z (pronounced “Zulu”) means UTC, and of you don’t parse it as such, you will get incorrect times (on most JVMs). Instant.parse efficiently avoids any problems here.
Don’t store date-tine as a string
It looks like you are are storing start time in a String field in your object? That would be poor modelling. Use a proper date-time type. Strings are for interfaces. Date-time classes like Instant offer much more functionality, for example define sort order.
You have two main approaches:
Make your class implement Comparable
Use a custom Comparator
Then, you can choose the field to compare from, and transform it.
IE (implementing comparable):
class Example implements Comparable<Example> {
private String stringDate;
public int compareTo(Example e) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date date1 = formatter.parse(this.stringDate);
Date date2 = formatter.parse(e.stringDate);
return date1.getTime() - date2.getTime();
}
}
And then using Arrays.sort would use your custom comparison.
Let your class implement Comparable and implement compareTo using modern formatting and date classes. Note that LocalDateTime also implements Comparable so once the string has been parsed you let LocalDateTime do the comparison
public class MyTimes implements Comparable<MyTimes> {
private final DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;
//other code
public int compareTo(MyTimes o) {
LocalDateTime thisDate = LocalDateTime.from(dtf.parse(this.getStartTime()));
LocalDateTime otherDate = LocalDateTime.from(dtf.parse(o.getStartTime()));
return thisDate.compareTo(otherDate);
}
}
You can also create a separate class as a comparator if this comparison is special and what you not always want to use
public class MyTimesComparator implements Comparator<MyTimes> {
#Override
public int compare(MyTimes arg0, MyTimes arg1) {
DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;
LocalDateTime thisDate = LocalDateTime.from(dtf.parse(this.getStartTime()));
LocalDateTime otherDate = LocalDateTime.from(dtf.parse(o.getStartTime()));
return thisDate.compareTo(otherDate);
}
}
and then use it like
someList.sort(new MyTimesComparator());
or use an inline function (I am using Instant here)
someList.sort( (m1, m2) -> {
DateTimeFormatter dtf = DateTimeFormatter.ISO_INSTANT;
Instant instant1 = Instant.from(dtf.parse(m1.getStartTime));
Instant instant2 = Instant.from(dtf.parse(m2.getStartTime));
return intant1.compareTo(instant2);
});
I noticed now that you have an array and not a list so you need to convert to a list or use Arrays.sort instead.

Java 8 best way to parse text date to millisecond timestamp

I want to create a Java class with thread-safe static methods to parse dates. I understand that some of the Java 7 (and earlier) date time classes are not thread-safe. What is the best thread-safe implementation in Java 8 of this functionality:
String text = "5/16/2008";
long timestamp = DateUtil.getTimestamp(text);
In Java 7 and earlier, you would do this:
public class DateUtil {
public static long getTimestamp(String text) {
DateFormat df = new SimpleDateFormat("M/d/yyyy");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
long timestamp = df.parse(text).getTime();
return timestamp;
}
}
But instead of creating a new instance of DateFormat for every call, I want to share a single static instance for all calls to this static getTimestamp method. My understanding is that this is not thread-safe.
One key requirement is that the text I want to parse has a short date like "5/16/2008" without HH:mm:ss resolution.
I also don't want to use a third party library like Joda-Time, but rather only standard Java 8 classes.
Here's a version of your code refactored to use the java.time.* package in Java 8. It uses a static final formatter instance, which is thread-safe and immutable, unlike java.text.SimpleDateFormat.
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class DateUtil {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
public static long getTimestamp(String text) {
LocalDate localDate = LocalDate.parse(text, formatter);
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()).getTime();
}
}
You can use joda-time lib. DateTime is immutable - and once created the values do not change, so class can safely be passed around and used in multiple threads without synchronization.
A companion mutable class to DateTime is MutableDateTime, of which the class can be modified and are not thread-safe.
DateTimeFormatter formatter = DateTimeFormat.forPattern("M/d/yyyy'T'HH:mm:ss.SSSZZ")
.withLocale(Locale.ROOT).withChronology(ISOChronology.getInstanceUTC());
DateTime dt = formatter.parseDateTime(text);
Reference of DateTimeFormatt: DatetimeFormat api.
As stated in ck1's answer, usage of java.time API is a better approach than the legacy classes. DateTimeFormatter is immutable and thread-safe, and using a static final instance of it will solve your problem.
The only part where I differ from that answer is in the code , where the Date class is used to get the time. I would like to take the java.time approach here as well. Below is my version :
public class DateUtil {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
public static long getTimestamp(String text) {
LocalDate localDate = LocalDate.parse(text, formatter);
return Instant.from(localDate.atStartOfDay(ZoneId.systemDefault())).toEpochMilli();
}
public static void main(String[] args) {
String text = "5/16/2008";
long timestamp = DateUtil.getTimestamp(text);
System.out.println(timestamp);
}
}

Static Variables Not Affecting Other Objects in Java Calendar Class

Since the Calendar class in Java has static data fields such as DATE, why don't the other objects change when the static field is modified?
I have made two different Gregorian Calendars and thought static data fields changed the value for all of the objects instead of one.
import java.util.Calendar;
import java.util.GregorianCalendar;
public class TEST {
public static void main(String[] args) {
GregorianCalendar cal = new GregorianCalendar();
System.out.println(cal.get(Calendar.DATE));
GregorianCalendar cal2 = new GregorianCalendar();
cal2.set(Calendar.DATE, 12);
System.out.println(cal2.get(Calendar.DATE));
System.out.println(cal.get(Calendar.DATE));
}
}
Calendar.DATE is not a static field, it's a static variable that's used to reference which type of value you want to set/get in a specific Calendar instance.
If you look at the actual source code of java.util.Calendar you would see that it has an internal int array that holds all the values, i.e. day, month, year, etc.
Calendar.DATE is just a nice way of referencing the fifth element of that array.
Declaration of member in the Java 8 source code.
/**
* Field number for <code>get</code> and <code>set</code> indicating the
* day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
* The first day of the month has value 1.
*
* #see #DAY_OF_MONTH
*/
public final static int DATE = 5;
The Answer by rorschach is correct and should be accepted.
Also, you are using old date-time classes that have proven to be poorly designed, confusing, and troublesome. Avoid them. They have been supplanted by the java.time classes.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate nextWeek = today.plusWeeks( 1 );
LocalDate midMonth = today.withDayOfMonth( 15 );
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate secondTuesdayOfThisMonth = today.with( TemporalAdjusters.dayOfWeekInMonth( 2 , DayOfWeek.TUESDAY ) );

Converting java.sql.Date to java.util.Date

What's the simplest way to convert a java.sql.Date object to a java.util.Date while retaining the timestamp?
I tried:
java.util.Date newDate = new Date(result.getDate("VALUEDATE").getTime());
with no luck. It's still only storing the date portion into the variable.
The class java.sql.Date is designed to carry only a date without time, so the conversion result you see is correct for this type. You need to use a java.sql.Timestamp to get a full date with time.
java.util.Date newDate = result.getTimestamp("VALUEDATE");
If you really want the runtime type to be util.Date then just do this:
java.util.Date utilDate = new java.util.Date(sqlDate.getTime());
Brian.
Since java.sql.Date extends java.util.Date, you should be able to do
java.util.Date newDate = result.getDate("VALUEDATE");
This function will return a converted java date from SQL date object.
public static java.util.Date convertFromSQLDateToJAVADate(
java.sql.Date sqlDate) {
java.util.Date javaDate = null;
if (sqlDate != null) {
javaDate = new Date(sqlDate.getTime());
}
return javaDate;
}
From reading the source code, if a java.sql.Date does actually have time information, calling getTime() will return a value that includes the time information.
If that is not working, then the information is not in the java.sql.Date object. I expect that the JDBC drivers or the database is (in effect) zeroing the time component ... or the information wasn't there in the first place.
I think you should be using java.sql.Timestamp and the corresponding resultset methods, and the corresponding SQL type.
In the recent implementation, java.sql.Data is an subclass of java.util.Date, so no converting needed.
see here: https://docs.oracle.com/javase/1.5.0/docs/api/java/sql/Date.html

Categories