21

i'm managing a date that comes from an Alfresco Properties and is in the specified (Tue Jul 13 00:00:00 CEST 2010) and i need to convert it to a Java date...i've looked around and found millions of posts for various string to date conversion form and also this page and so i tried something like this:

private static final DateFormat alfrescoDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);

But it throws an exception.(The exception is (SSollevata un'eccezione durante la gestione della data: java.text.ParseException: Unparseable date: "Tue Jul 13 00:00:00 CEST 2011").

I post the complete code:

        try {
            QName currDocTypeQName = (QName) nodeService.getType(doc);
            log.error("QName:["+currDocTypeQName.toString()+"]");
            if (currDocTypeQName != null) {
                String codAtto = AlfrescoConstants.getCodAttoFromQName(currDocTypeQName.toString());
                log.error("codAtto:["+codAtto+"]");
                if (codAtto.equals(AlfrescoConstants.COD_IQT)){
                    List<ChildAssociationRef> risposteAssociate = nodeService.getChildAssocs(doc, AlfrescoConstants.QN_RISPOSTEASSOCIATE, RegexQNamePattern.MATCH_ALL);
                    for (ChildAssociationRef childAssocRef : risposteAssociate) {
                        // Vado a prendere il nodo
                        NodeRef risposta = childAssocRef.getChildRef();
                        String dataRisposta = (nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)).toString();
                        log.error("dataRisposta:["+dataRisposta+"]");
                        if (!dataRisposta.isEmpty()){
                            try {
                                Date dataDa = dmyFormat.parse(req.getParameter("dataDa"));
                                log.error("dataDa:["+dataDa.toString()+"]");
                                Date dataA = dmyFormat.parse(req.getParameter("dataA"));
                                log.error("dataA:["+dataA.toString()+"]");
                                Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
                                log.error("dataRispostaDate:["+dataRispostaDate.toString()+"]");

                                if (dataRispostaDate.after(dataDa) && dataRispostaDate.before(dataA)){
                                    results.add(doc);
                                    log.error("La data risposta  è compresa tra le date specificate");
                                }else{
                                    log.error("La data risposta non è compresa tra le date specificate");
                                }
                            } catch (ParseException e) {
                                log.error("Sollevata un'eccezione durante la gestione della data: " + e);
                                throw new RuntimeException("Formato data non valido");
                            }
                        }else{
                            log.error("La data risposta non è specificata");
                        }
                    }
                }else{
                    results.add(doc);
                }
            }
        } catch (Exception e) {
            log.error("Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola: " + e);
        }

Anyone can help?

Nicola Peluchetti
  • 72,169
  • 29
  • 129
  • 186
  • 1
    Couldy ou expand on "it doesn't work"? What happens? – Jon Skeet May 09 '11 at 12:43
  • It throws an exception. Should be a parse exception but i'll check to be sure! – Nicola Peluchetti May 09 '11 at 12:47
  • I tried that format with the string you provided, and got an appropriate response, with no exception. Can you include the stack trace from the exception? – Sean Reilly May 09 '11 at 12:48
  • @Nicola: For questions like this, *always* include all the relevant information for exceptions - the type and the error message. – Jon Skeet May 09 '11 at 12:49
  • Ok, sorry, i'm new to java, i think there is no stack trace because it's inside a try-catch block, how can i print the stack trace in the catch block? – Nicola Peluchetti May 09 '11 at 12:52
  • 1
    @Nicola Assuming that "log" is log4j or java.util.logging, change the line in the catch block to: log.error(""Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola", e); – Sean Reilly May 09 '11 at 12:59
  • Sollevata un'eccezione durante la gestione della data: java.text.ParseException: Unparseable date: "Tue Jul 13 00:00:00 CEST 2011" This is the exception – Nicola Peluchetti May 09 '11 at 13:00
  • Of course it also catches "Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola: java.lang.RuntimeException: Formato data non valido" – Nicola Peluchetti May 09 '11 at 13:05
  • What's the data type of AlfrescoConstants.QN_DATA_RISPOSTA in your data model? If it's a cm:Date, then you should just be able to cast the property to a Java date – Gagravarr May 09 '11 at 13:36
  • 1
    its defined like this: Data risposta d:date You mean the this should work? Date dataRisposta = (Date)(nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)); – Nicola Peluchetti May 09 '11 at 13:49
  • 1
    @Gagravarr you are right, it works!If you answer the thread i'll mark your answer as accepted. – Nicola Peluchetti May 09 '11 at 14:06
  • @Nicola Glad it worked! I've added it as an answer – Gagravarr May 09 '11 at 14:33
  • @NicolaPeluchetti can you please mark JMelnik's answer as accepted? Gragravarr's answer is to localized. Similar problem happend to me outside Alfresco so Gragravarr's answer was useless. JMelnik's worked. – Emperor Orionii Jul 16 '13 at 14:44
  • 1
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 14 '18 at 03:45

5 Answers5

29

Basically your problem is that you are using a SimpleDateFormat(String pattern) constructor, where javadoc says:

Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the default locale.

And if you try using this code:

DateFormat osLocalizedDateFormat = new SimpleDateFormat("MMMM EEEE");
System.out.println(osLocalizedDateFormat.format(new Date()))

you will notice that it prints you month and day of the week titles based on your locale.

Solution to your problem is to override default Date locale using SimpleDateFormat(String pattern, Locale locale) constructor:

DateFormat dateFormat = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
dateFormat.parse("Tue Jul 13 00:00:00 CEST 2011");
System.out.println(dateFormat.format(new Date()));
JMelnik
  • 6,216
  • 2
  • 24
  • 40
  • This makes a lot of sense. @Nicola, is your default locale Italian? – Sean Reilly May 09 '11 at 14:10
  • yes it is. I think this is a really good suggestion.I've marked the other one as answer because my issue was "Alfresco Related" and the other answer is much cleaner in my situation, but thanks for the answer! – Nicola Peluchetti May 09 '11 at 14:39
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 14 '18 at 03:45
  • IDK whats happening with this code, what I just wanted was for my input of 2019/05/05 be save on the DB as 2019/05/05. But when running what was being save on the parse date, im receiving with a format like this "Tue Jul 13 00:00:00 CEST 2011" but what was being save on the DB is 2019/05/05. I'm confused as to why the actual value I know should be saved is different from what is being saved on the DB, or is there some hidden processes going around?. Anyhow now my date now parses correctly, so great. thx.. – iamjoshua Apr 28 '19 at 11:48
6

tl;dr

ZonedDateTime.parse(                     // Produce a `java.time.ZonedDateTime` object.
    "Wed Jul 13 00:00:00 CEST 2011" ,    // Corrected `Tue` to `Wed`.
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  ) 
)

2011-07-13T00:00+02:00[Europe/Paris]

Bad data: Wed vs Tue

You input string Tue Jul 13 00:00:00 CEST 2011 is invalid. July 13 of 2011 was a Wednesday, not a Tuesday.

String input = "Wed Jul 13 00:00:00 CEST 2011" ;  // Corrected `Tue` to `Wed`.

screen shot of July 2011 calendar in Duck Duck Go search engine

java.time

The modern approach uses the java.time classes rather than the troublesome old legacy date-time classes seen in other Answers.

Define a formatting pattern to match your input string. Notice the Locale, which defines the human language to be used in parsing name of month and name of day-of-week.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  );
ZonedDateTime zdt = ZonedDateTime.parse( input , f  );

zdt.toString(): 2011-07-13T00:00+02:00[Europe/Paris]

Time zone

Your CEST is a pseudo-zone, not a true time zone. Never use these. They are not standardized, and are not even unique(!).

The ZonedDateTime class will make a valiant effort at guessing the intention behind such a 3-4 character pseudo-zone. Your CEST happened to work here, interpreted as Europe/Paris time zone. But you cannot rely on the guess being 100% successful. Instead, avoid such pseudo-zones entirely.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland.

ZoneId z = ZoneId.of( "Europe/Paris" );  // https://time.is/Paris
LocalDate today = LocalDate.now( z );  // Current date varies around the globe by zone.

ISO 8601

Your input string’s format is terrible. When serializing date-time values as text, use only the standard ISO 8601 formats.

The ZonedDateTime class wisely extends the standard format by appending the name of the time zone in square brackets as seen in examples above.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 218,480
  • 72
  • 657
  • 915
6

Based on your comments, I believe that your property is actually of type d:date or d:datetime. If so, the property will already be coming back from Alfresco as a java Date object. So, all you'd need to do is:

  NodeRef risposta = childAssocRef.getChildRef();
  Date dataRisposta = (Date)nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA);
Gagravarr
  • 43,370
  • 9
  • 94
  • 140
1

The problem is that CEST is not a timezone Java supports. You can use "CST".

The Javadoc for TimeZone notes:

Three-letter time zone IDs For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

For three/four letter timezone support I suggest you try JodaTime which may do a better job.


String dataRisposta = "Tue Jul 13 00:00:00 CST 2010";
Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
System.out.println(dataRispostaDate);

prints

Tue Jul 13 07:00:00 BST 2010

String[] ids = TimeZone.getAvailableIDs();
Arrays.sort(ids);
for (String id : ids) {
    System.out.println(id);
}

prints

...
CAT
CET
CNT
CST
CST6CDT
CTT
...
Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075
  • The problem is that the string is a property of an alfresco Node. I take it with: String dataRisposta = (nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)).toString(); – Nicola Peluchetti May 09 '11 at 12:51
  • It doesn't throw an exception for me. If you know you want `CEST` to mean `CST` or some other time-zone you can use `.replaceAll("CEST", "CST")` – Peter Lawrey May 09 '11 at 12:53
  • I don't think that this answer is right. The spec for SimpleDateFormat (http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html#rfc822timezone) says that "For parsing, RFC 822 time zones are also accepted." These are 4 letter time zones; I assume that CEST is one of these. When I ran the example, it worked fine without complaining about the time zone format, and returned a reasonable result. – Sean Reilly May 09 '11 at 12:56
  • @Sean Reilly, I assume you didn't read my whole answer "CEST is NOT a supported time zone in Oracle Java 6 update 23. It doesn't give me an error either, it just gives me the time in the local timezone. – Peter Lawrey May 09 '11 at 13:02
  • in my log i have errors every time i try to parse that date also if it has CET: Sollevata un'eccezione durante la gestione della data: java.text.ParseException: Unparseable date: "Tue Jan 18 00:00:00 CET 2011" or Sollevata un'eccezione durante la gestione della data: java.text.ParseException: Unparseable date: "Wed Jun 23 00:00:00 CEST 2010" – Nicola Peluchetti May 09 '11 at 13:02
  • @Nicola, Both parse for me. I suspect you are using an older version of Java. Which version do you have? – Peter Lawrey May 09 '11 at 13:04
  • @Sean Reilly, the four digit timezone consists of "Sign TwoDigitHours Minutes" but not letters. – Peter Lawrey May 09 '11 at 13:10
  • From the log i get: 15:11:37,172 INFO [service.descriptor.DescriptorService] Alfresco JVM - v1.6.0_16-b01; maximum heap size 938,688MB – Nicola Peluchetti May 09 '11 at 13:12
  • I would try Java 6 update 25 if you can. Update 16 may be old enough to have a problem with this. – Peter Lawrey May 09 '11 at 13:17
  • @Peter: I did read the entire answer, but I'm not sure that I agree with it. There's no guarantee that TimeZone and SimpleDateFormat support the same list of time zones; SimpleDateFormat explicitly lists specific formats that it will support for parsing but not for formatting, so it's entirely reasonable that it might support extra stuff not included in TimeZone. More importantly, I *tried it and got it to work* (With 1.6.0_24 for osx, btw). It certainly seems like a reasonable time zone to parse -- it is an official time zone name. – Sean Reilly May 09 '11 at 13:30
  • FYI for those who don't live in europe: CEST != CET, and CEST != CST. CEST is a central european time zone with daylight saving time (Central European Summer Time), and is equivalent to GMT + 2. Certainly converting CEST -> CST is not right. – Sean Reilly May 09 '11 at 13:33
  • @Sean, Sorry for getting annoyed. I have been meaning to download Java 6 update 25. It may be that an update is all that is required. ;) – Peter Lawrey May 09 '11 at 13:37
  • @Peter: No worries. If it does work on 6.0_24+ and not earlier, then I will be annoyed (but not with you). Is it just me, or is this starting to feel like a java/portability bug? – Sean Reilly May 09 '11 at 13:45
  • 1
    Updating didn't work, but it worked using this line: Date dataRisposta = (Date)(nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)); – Nicola Peluchetti May 09 '11 at 14:07
  • In other words there was no need to parse it. That did cross my mind. ;) – Peter Lawrey May 09 '11 at 16:45
  • 1
    FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jan 14 '18 at 01:35
0

Try this function I had the same issue.

public String getMyDate(String myDate, String requiredFormat, String mycurrentFormat) {
    DateFormat dateFormat = new SimpleDateFormat(returnFormat);
    Date date = null;
    String returnValue = "";
    try {
        date = new SimpleDateFormat(myFormat, Locale.ENGLISH).parse(myDate);
        returnValue = dateFormat.format(date);
    } catch (ParseException e) {
        returnValue = myDate;
    }
    return returnValue;
}

Example:

Wed May 06 13:01:29 EDT 2020 i.e "EEE MMM dd HH:mm:ss zzz yyyy" is mycurrentFormat

4.May.2020 i.e. "d.MMM.yyyy" is my requiredFormat

Date date = new Date();

getMyDate(date.toString(), "d.MMM.yyyy", "EEE MMM dd HH:mm:ss zzz yyyy")
Aasim ali
  • 88
  • 6
  • Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Also your code is longer than the code in most of the other answers. Has it got any advantages over those? – Ole V.V. May 07 '20 at 13:31