74

I am coding this with Groovy

I am currently trying to convert a string that I have to a date without having to do anything too tedious.

String theDate = "28/09/2010 16:02:43";
def newdate = new Date().parse("d/M/yyyy H:m:s", theDate)

Output:

Tue Aug 10 16:02:43 PST 2010

The above code works just fine, however when my string changes to something like:

String testDate = "Tue Aug 10 16:02:43 PST 2010"
def newerdate = new Date().parse("d/M/yyyy H:m:s", testDate)

It tells me that "there is no such value for Tue". I tried to throw an 'E' in the parse for the date but it said the date was not able to be parsed.

Can someone explain how I should go about parsing the second example?

StartingGroovy
  • 2,802
  • 9
  • 47
  • 66

7 Answers7

75

The first argument to parse() is the expected format. You have to change that to Date.parse("E MMM dd H:m:s z yyyy", testDate) for it to work. (Note you don't need to create a new Date object, it's a static method)

If you don't know in advance what format, you'll have to find a special parsing library for that. In Ruby there's a library called Chronic, but I'm not aware of a Groovy equivalent. Edit: There is a Java port of the library called jChronic, you might want to check it out.

Mark Thomas
  • 37,131
  • 11
  • 74
  • 101
  • 5
    As of JDK version 1.1, replaced by DateFormat.parse(String s) – Alexander Suraphel Feb 15 '14 at 09:49
  • 9
    @AlexanderSuraphel, it's rather about Groovy `Date`, my friend. – Adeel Ansari Oct 19 '16 at 08:02
  • From 2.5.0, however, there has been a breaking change and those enhancements are not shipped anymore with groovy-all. So, going forward, they need to be included as a separate module, named groovy-dateutil. [See here.](https://www.baeldung.com/groovy-string-to-date) – Saikat Dec 16 '19 at 11:51
28

Try this:

def date = Date.parse("E MMM dd H:m:s z yyyy", dateStr)

Here are the patterns to format the dates

Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
gcores
  • 12,376
  • 2
  • 49
  • 45
  • 5
    `Date.parse` is **deprecated**. Use `DateFormat.parse()` instead. – Cristian Gonçalves Feb 01 '18 at 12:27
  • 1
    I know this is old, but `Date.parse(String, String)` is [not deprecated in groovy](http://docs.groovy-lang.org/docs/groovy-2.4.4/html/groovy-jdk/java/util/Date.html#parse%28java.lang.String,%20java.lang.String%29) (which is the language used here if I am to believe the question's tags). – sensei Nov 12 '19 at 09:43
  • There is an online date format tester, which I found useful http://sdfonlinetester.info/# – Cris Rockwell Feb 07 '20 at 16:22
24

JChronic is your best choice. Here's an example that adds a .fromString() method to the Date class that parses just about anything you can throw at it:

Date.metaClass.'static'.fromString = { str ->
    com.mdimension.jchronic.Chronic.parse(str).beginCalendar.time
}

You can call it like this:

println Date.fromString("Tue Aug 10 16:02:43 PST 2010")
println Date.fromString("july 1, 2012")
println Date.fromString("next tuesday")
ataylor
  • 64,891
  • 24
  • 161
  • 189
7

Date#parse is deprecated . The alternative is :

java.text.DateFormat#parse 

thereFore :

 new SimpleDateFormat("E MMM dd H:m:s z yyyy", Locale.ARABIC).parse(testDate)

Note that SimpleDateFormat is an implementation of DateFormat

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
  • 11
    He is not using parse(String) but parse(format, date) which comes from groovy not java. This method is not deprecated. – John Mercier Apr 16 '15 at 18:04
  • 2
    Wrong API function: you mention: java Date.parse(String), question is about: Groovy Date.parse(String, String), which isn't deprecated! – lospejos Jul 28 '16 at 10:36
5

Googling around for Groovy ways to "cast" a String to a Date, I came across this article: http://www.goodercode.com/wp/intercept-method-calls-groovy-type-conversion/

The author uses Groovy metaMethods to allow dynamically extending the behavior of any class' asType method. Here is the code from the website.

class Convert {
    private from
    private to

    private Convert(clazz) { from = clazz }
    static def from(clazz) {
        new Convert(clazz)
    }

    def to(clazz) {
        to = clazz
        return this
    }

    def using(closure) {
        def originalAsType = from.metaClass.getMetaMethod('asType', [] as Class[])
        from.metaClass.asType = { Class clazz ->
            if( clazz == to ) {
                closure.setProperty('value', delegate)
                closure(delegate)
            } else {
                originalAsType.doMethodInvoke(delegate, clazz)
            }
        }
    }
}

They provide a Convert class that wraps the Groovy complexity, making it trivial to add custom as-based type conversion from any type to any other:

Convert.from( String ).to( Date ).using { new java.text.SimpleDateFormat('MM-dd-yyyy').parse(value) }

def christmas = '12-25-2010' as Date

It's a convenient and powerful solution, but I wouldn't recommend it to someone who isn't familiar with the tradeoffs and pitfalls of tinkering with metaClasses.

Jayan
  • 18,003
  • 15
  • 89
  • 143
Doug Paul
  • 1,221
  • 12
  • 16
1

I think the best easy way in this case is to use parseToStringDate which is part of GDK (Groovy JDK enhancements):

Parse a String matching the pattern EEE MMM dd HH:mm:ss zzz yyyy containing US-locale-constants only (e.g. Sat for Saturdays). Such a string is generated by the toString method of Date

Example:

println(Date.parseToStringDate("Tue Aug 10 16:02:43 PST 2010").format('MM-dd-yyyy'))
Ibrahim.H
  • 1,062
  • 1
  • 13
  • 22
0

Below is the way we are going within our developing application.

import java.text.SimpleDateFormat

String newDateAdded = "2018-11-11T09:30:31"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
Date dateAdded = dateFormat.parse(newDateAdded)

println(dateAdded)

The output looks like

Sun Nov 11 09:30:31 GMT 2018

In your example, we could adjust a bit to meet your need. If I were you, I will do:

String datePattern = "d/M/yyyy H:m:s"
String theDate = "28/09/2010 16:02:43"
SimpleDateFormat df = new SimpleDateFormat(datePattern)
println df.parse(theDate)

I hope this would help you much.

Tung
  • 1,579
  • 4
  • 15
  • 32