DST Handling In Java 5 For Corner Dates - java

According to the following website daylight saving time in UK starts from 27 Mar-2016 1:00:00 (24 hours time format)
http://www.timeanddate.com/time/change/uk/london?year=2016
Then why the following code prints false?
import java.text.ParseException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class BSTGMTDetector
{
public static void main(String[] args) throws ParseException
{
TimeZone def = TimeZone.getTimeZone("Europe/London");
Calendar cal = new GregorianCalendar();
cal.clear();
cal.set(2016, 2, 27,2,01,01);
boolean isInDaylight = def.inDaylightTime(cal.getTime());
System.out.println("Date[" + cal.getTime() + "] is in DST[" + isInDaylight + "]");
}
}
Output : Date[Sun Mar 27 02:01:01 IST 2016] is in DST[false]

It seems that your system maintain IST.When you define,
Calendar cal = new GregorianCalendar();
Timezone for cal variable is IST.So,when call
def.inDaylightTime(cal.getTime());
Date is passed to this method in IST timezone.So,DST start for UK at 27th MAR,06:30:00 IST.
Hence.your O/P behaviour.

Related

DateTime addmonths method is adding 1 extra day

I am currently working on an issue where DateTime.addMonths(iStartDateH, durationAsInt) is adding an extra day. It uses GeorgianCalendar internally.
We are using Java 5 currently in this project
Eg: For 24 months
ExpirationDate=DateTime.addMonths(currentDate, 24)
CurrentDate= 01/02/2021 (dd/mm/yyyy format)
ExpirationDate= 02/02/2023
public static ErrorCode addMonths(DateHolder dateH, int numMonths) {
try {
Calendar c = new GregorianCalendar();
c.setTime(dateH.value);
c.add(Calendar.MONTH, numMonths);
dateH.value = c.getTime();
return ErrorCode.successCN;
}
catch (Exception e) {
IlMessage msg = new IlMessage(Msg.exceptionCaughtCN, e);
IlSession.getSession().getMessageStack().push(msg);
return ErrorCode.errorCN;
}
}
I tried checking the complete date/time difference and its coming as 730.773935185185185
Please help with the same.
I am using Java 8 and I tried the code below and it worked just fine for me (for testing purposes I set the date as Feb 1 as from your example.
public static void main(String...pStrings) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate currentDate = LocalDate.of(2021, 2, 1); //LocalDate.now();
System.out.println("Original Date -" +currentDate.format(formatter));
LocalDate newDate = currentDate.plusMonths(24);
System.out.println("updated date - " + newDate.format(formatter));
}
I received the output: -
Original Date -01/02/2021
updated date - 01/02/2023
Note that m is for minutes. For a month, you need to use M.
The implementation of your class, DateHolder seems to have a problem. There is no such problem with java.util date-time API for this requirement.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH).parse("01/02/2021"));
System.out.println(calendar.getTime());
int numMonths = 24;
calendar.add(Calendar.MONTH, numMonths);
System.out.println(calendar.getTime());
}
}
Output:
Mon Feb 01 00:00:00 GMT 2021
Wed Feb 01 00:00:00 GMT 2023

SimpleDateFormat adds random milliseconds while formatting to string [duplicate]

This question already has answers here:
Java Calendar adds a random number of milliseconds?
(4 answers)
Closed 2 years ago.
I am trying to format the date to ISO8601("yyyy-MM-dd'T'HH:mm:ss.SSSZ") using SimpleDateFormat, but formatted string seems to have random values at milliseconds place.
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DemoApplication {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
calendar.set(2020, 5 , 22, 17, 30, 00);
Date date = calendar.getTime();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String s = df.format(date);
System.out.println(s);
}
}
Output on multiple runs:
2020-06-22T17:30:00.886+0530
2020-06-22T17:30:00.049+0530
2020-06-22T17:30:00.799+0530
In the above output, everything is consistent except milliseconds after dot(.), Can someone explain this?
In the above output, everything is consistent except milliseconds
after dot(.), Can someone explain this?
The reason is that your format has milliseconds but you haven't set milliseconds in the Calendar instance; therefore, it gives you the milliseconds of the moment when you run your code.
You can verify the same using the following code:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
calendar.set(2020, 5, 22, 17, 30, 00);
Date date = calendar.getTime();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String s = df.format(date);
System.out.println(s);
System.out.println(date.toInstant().getNano()); // Added this line
}
}
Output:
2020-06-22T17:30:00.425+0100
425000000
On a side note, I recommend you stop using outdated date-time API and start using the modern date-time API.
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = LocalDateTime.of(2020, 5, 22, 17, 30, 00).atZone(ZoneId.systemDefault());
System.out.println(zdt);
}
}
Milliseconds aren't covered by
calendar.set(2020, 5 , 22, 17, 30, 00);
you can an extra Line to set them to 0:
calendar.set(Calendar.MILLISECOND, 0);
so that your program looks like this:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DemoApplication {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
calendar.set(2020, 5 , 22, 17, 30, 00);
calendar.set(Calendar.MILLISECOND, 0);
Date date = calendar.getTime();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String s = df.format(date);
System.out.println(s);
}
}
The JavaDocs of java.util.Calendar state the following for the method getInstance():
Gets a calendar using the specified time zone and default locale. The Calendar returned is based on the current time in the given time zone with the default locale.
That means you are getting the actual moment and then by calendar.set(2020, 5 , 22, 17, 30, 00); you set year, month, day, hours, minutes and seconds but you are not changing the smaller units of time which will stay as they were when you called Calendar calendar = Calendar.getInstance(TimeZone.getDefault());. That's not random, it's the current millis at that very moment of calling getInstance().
For a possibility of setting the milliseconds of a Calendar to any specific value, have a look at the answer given by #Norwort.
I think you shouldn't be using the outdated datetime classes from java.util. Instead, use java.time, maybe like this:
public static void main(String[] args) throws ParseException {
ZonedDateTime zonedDateTime = ZonedDateTime.of(2020, 5, 22, 17, 30, 0, 0,
ZoneId.systemDefault());
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String s = zonedDateTime.format(dtf);
System.out.println(s);
}
Which prints
2020-05-22T17:30:00.000+0200
when executed on my system, which has an offset of +02:00 at the moment.
The output on your system might differ, but will have set milliseconds and smaller units of time to 0.

Unexpected Behavior using Dates in Java

I have the following code:
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import org.junit.Test;
public class DateCalendarTest {
#Test
public void test1() {
private final DateFormat df1 = new SimpleDateFormat("MM/dd/yyyy");
String batchdt = "2015/09/23";
System.out.println("Date & Calendar Test: " + batchdt);
Calendar cal = Calendar.getInstance();
Date date1 = df1.parse(batchdt);
cal.setTime(date1);
System.out.println("Date & Calendar Test: " + cal.getTime());
}
}
Output:
Date Calendar Test: 2015/09/23
Date Calendar Test: Mon Nov 09 00:00:00 EST 190
Can someone please explain why this behaves in this manner?
Your intended data doesn't match the format specified in your SimpleDateFormat. However, by default, it is lenient in how it parses the data. For example, September 31st would be interpreted as October 1st.
Here, it's interpreted as day 9 of month 2,015 of year 23. 2,015 months is 167 years, 11 months, which when added to the year 23 yields the year 190. In this case, it is very lenient.
The output format is what is expected when printing out a Date directly.

How do I convert a java.sql.Date object into a GregorianCalendar?

I thought I'd be able to create a GregorianCalendar using the constructor that takes the year, month, and day, but I can't reliably get those fields from an instance of the java.sql.Date class. The methods that get those values from java.sql.Date are deprecated, and the following code shows why they can't be used:
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println("Year: " + date.getYear());
System.out.println("Month: " + date.getMonth());
System.out.println("Day: " + date.getDate());
System.out.println(date);
Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth(), date.getDate());
System.out.println(cal.getTime());
}
}
Here's the output, showing that the month and year are not returned correctly from the deprecated getYear() and getMonth() methods of Date:
Year: 111
Month: 11
Day: 25
2011-12-25
Thu Dec 25 00:00:00 EST 111
Since I can't use the constructor that I tried above, and there's no GregorianCalendar constructor that just takes a Date, how can I convert a java.sql.Date object into a GregorianCalendar?
You have to do this in two steps. First create a GregorianCalendar using the default constructor, then set the date using the (confusingly named) setTime method.
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println(date);
Calendar cal = new GregorianCalendar();
cal.setTime(date);
System.out.println(cal.getTime());
}
}
Here's the output:
2011-12-25
Sun Dec 25 00:00:00 EST 2011
I'm going from memory, but have you tried
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(rs.getDate());
Try this.
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println(date);
Calendar cal = new GregorianCalendar();
cal.setTime(date);
System.out.println(cal.getTime());
}
}
Use setTimeInMillis():
java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
I think this is the simplest way.

Fixed length of month and day in date format?

Is there any way to format Date object to made fixed length of Day and Month in order to have good alignment in a column?
For example:
15 May 2010
10 January 2010
Instead of
15 May 2010
10 January 2010
Thanks!
Have a look at the java.util.Formatter class whose format method is the same as String.format(...) and similar to System.out.printf.
For example:
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class FormatDateCalendar {
public static final String FORMAT_STRING = "%1$-3td %1$-9tB %1$tY";
public static void main(String[] args) {
Calendar c1 = new GregorianCalendar(2011, Calendar.FEBRUARY, 3);
Calendar c2 = new GregorianCalendar(2010, Calendar.MAY, 15);
Date today = new Date();
System.out.printf(FORMAT_STRING + "%n", c1);
System.out.printf(FORMAT_STRING + "%n", c2);
System.out.printf(FORMAT_STRING + "%n", today);
}
}

Categories

Resources