Top date Questions

List of Tags
1394
Freewind

If I run the following program, which parses two date strings referencing times one second apart and compares them:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000; 
    System.out.println(ld3);  
    System.out.println(ld4);  
    System.out.println(ld4-ld3);
}

The output is:

-1325491905
-1325491552
353

Why is ld4-ld3 not 1 (as I would expect from the one-second difference in the times), but 353?

If I change the dates to times one second later:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";  

Then ld4-ld3 will be 1


UPDATE

Java version:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)

Timezone(TimeZone.getDefault()):

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]

Locale(Locale.getDefault()): zh_CN
Answered By: Jon Skeet ( 3070)

It's a time zone change on December 31st in Shanghai.

See this page for details of 1927 in Shanghai. Basically at midnight at the end of 1927, the clocks went back 5 minutes and 52 seconds. So "1927-12-31 23:54:08" actually happened twice, and it looks like Java is parsing it as the later possible instant for that local date/time - hence the difference.

Just another episode in the often weird and wonderful world of time zones.

EDIT: Stop press! History changes...

The original question would no longer demonstrate quite the same behaviour, if rebuilt with version 2013a of TZDB. In 2013a, the result would be 358 seconds, with a transition time of 23:54:03 instead of 23:54:08.

I only noticed this because I'm collecting questions like this in Noda Time, in the form of unit tests... The test has now been changed, but it just goes to show - not even historical data is safe.

315
Naga Kiran

I noticed that JavaScript's new Date() function is very smart in accepting dates in several formats.

Xmas95 = new Date("25 Dec, 1995 23:15:00")
Xmas95 = new Date("2009 06 12,12:52:39")
Xmas95 = new Date("20 09 2006,12:52:39")

I could not find documentation anywhere showing all the valid string formats while calling new Date() function.

This is for converting a string to date. If we look at the opposite side that is converting date object to string, until now I was under the impression that JavaScript doesn't have a built-in API to format a date object into a string.

Editor's note: The following approach is the asker's attempt that worked on a particular browser but does not work in general; see the answers on this page to see some actual solutions.

Today, I played with the toString() method on the date object and surprisingly it serves the purpose of formatting date to strings.

var d1=new Date();
d1.toString('yyyy-MM-dd');       //returns "2009-06-29"
d1.toString('dddd, MMMM ,yyyy')  //returns "Monday, June 29,2009"

Also here I couldn't find any documentation on all the ways we can format the date object into a string.

Where is the documentation which lists the format specifiers supported by the Date() object?

Answered By: Haim Evgi ( 313)

I love 10 ways to format time and date using JavaScript and Working with Dates.

Basically, you have three methods and you have to combine the strings for yourself:

getDate(): Returns the date
getMonth(): Returns the month
getFullYear(): Returns the year

Example:

<script type="text/javascript">
    var d = new Date();
    var curr_date = d.getDate();
    var curr_month = d.getMonth() + 1; //Months are zero based
    var curr_year = d.getFullYear();
    document.write(curr_date + "-" + curr_month + "-" + curr_year);
</script>
165
orip

I'd like to tell the difference between valid and invalid date objects in JS, but couldn't figure out how:

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

Any ideas for writing an isValidDate function?

EDIT - thanks for the responses!

  • Ash recommended Date.parse for parsing date strings, which gives an authoritative way to check if the date string is valid.
  • What I would prefer, if possible, is have my API accept a Date instance and to be able to check/assert whether it's valid or not. Borgar's solution does that, but I need to test it across browsers. I also wonder whether there's a more elegant way.

EDIT 2

  • Ash made me consider not having my API accept Date instances at all, this would be easiest to validate.
  • Borgar suggested testing for a Date instance, and then testing for the Date's time value. If the date is invalid, the time value is NaN. I checked with ECMA-262 (section 15.9.5.9) and this behavior is in the standard, which is exactly what I'm looking for.

My final function, based on Borgar's solution:

function isValidDate(d) {
  if ( Object.prototype.toString.call(d) !== "[object Date]" )
    return false;
  return !isNaN(d.getTime());
}
Answered By: Borgar ( 113)

Here's how I would do it:

if ( Object.prototype.toString.call(d) === "[object Date]" ) {
  // it is a date
  if ( isNaN( d.getTime() ) ) {  // d.valueOf() could also work
    // date is not valid
  }
  else {
    // date is valid
  }
}
else {
  // not a date
}
162
Kibbee

I am looking for a way to delete all files older than 7 days in an MS-DOS batch file. I've searched around the web, and found some examples with hundreds of lines of code, and others that required installing extra command line utilities to accomplish the task. Similar things can be done in BASH in just a couple lines of code. It seems that something at least remotely easy could be done for batch files in Windows. I'm looking for a solution that works in a standard Windows command prompt, without any extra utilities. Please no PowerShell or Cygwin either.

Answered By: aku ( 265)

Enjoy:

forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"

See forfile documentation for more details.

For more goodies refer to An A-Z Index of the Windows XP command line

If you don't have forfiles installed on your machine, get it from Microsoft FTP server. Place it to C:\WINDOWS\system32\forfiles.exe Recent versions of Windows and Windows Server have it installed by default.

Update Win7: Syntax has changed a little therefore the updated command is:

forfiles -p "C:\what\ever" -s -m *.* /D -<number of days> /C "cmd /c del @path"
161
mac

Isn't there a convenient way of getting from a java.util.Date to a XMLGregorianCalendar?

Answered By: Ben Noland ( 285)
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
145
Samuel

I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.

I wanted to sort an ArrayList of custom objects by one of their properties: a Date object (getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:

public class customComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class randomName {
    ...
    Collections.sort(Database.arrayList, new customComparator);
    ...
}

I just started with Java so please forgive my ignorance.

Answered By: Michael Myers ( 206)

Since Date implements Comparable, it has a compareTo method just like String does.

So your custom comparator could look like this:

public class CustomComparator implements Comparator<MyObject> {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
}

(The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.)

Your sorting code would be just about like you wrote:

Collections.sort(Database.arrayList, new CustomComparator());

 
A couple of smaller points which are not directly related to the question:

  1. By convention, classes start with an upper-case letter while methods and variables start with a lower-case letter. That's why I changed the name of the comparator to CustomComparator.
  2. Use the Javadocs. They will be invaluable if you keep working with Java.