1

I am writing a class to simplify all the operations that I could make with a GregorianCalendar. The operations that I need to make are: -Getting the date in string format, translated to Italian; -Making the subtraction between two dates. I havent' used Calendar,Date and Time classes because they have a lot of deprecated methods. Also, the tag isn't gregoriancalendar because I may need to use another class (but feel free to modify it if not agree). However this is the class:

package TruckingCompany;

import java.util.GregorianCalendar;
import java.util.Locale;

@SuppressWarnings("serial")
public class TCCalendar extends GregorianCalendar
{
public TCCalendar()
{
    super(Locale.ITALY);
}
@Override
public String toString()
{
    String str=new String();
    switch(get(DAY_OF_WEEK))
    {
        case 1: 
            str+="Domenica "; 
            break;
        case 2:
            str+="Lunedì ";
            break;
        case 3:
            str+="Martedì ";
            break;
        case 4:
            str+="Mercoledì ";
            break;
        case 5:
            str+="Giovedì ";
            break;
        case 6:
            str+="Venerdì ";
            break;
        case 7:
            str+="Sabato ";
            break;
    }
    str+=get(DAY_OF_MONTH);
    switch(get(MONTH))
    {
        case 0:
            str+=" Gennaio ";
            break;
        case 1:
            str+=" Febbraio ";
            break;
        case 2:
            str+=" Marzo ";
            break;
        case 3:
            str+=" Aprile ";
            break;
        case 4:
            str+=" Maggio ";
            break;
        case 5:
            str+=" Giungo ";
            break;
        case 6:
            str+=" Luglio ";
            break;
        case 7:
            str+=" Agosto ";
            break;
        case 8:
            str+=" Settembre ";
            break;
        case 9:
            str+=" Ottobre ";
            break;
        case 10:
            str+=" Novembre ";
            break;
        case 11:
            str+=" Dicembre ";
            break;
    }
    str+=get(YEAR)+ " Ore ";
    str+=get(HOUR_OF_DAY)+ ":";
    str+=get(MINUTE)+":";
    str+=get(SECOND);
    return str;
}
}

I use linux and the time is correctly set to 10:19 (Italian hour). But now (at 10:20 local hour) I get as result of the toString method:
"Venerdì 2 Marzo 2012 Ore 13:21:10" Don't look at the Italian stuff, the problem is the hour: get(HOUR_OF_DAY) returns 13 instead of 10 (22:21). Also, there is another class more intuitive? I have searched in javadoc and except Calendar,GregorianCalendar, Date and Time I haven't found anything else.

Ramy Al Zuhouri
  • 21,580
  • 26
  • 105
  • 187
  • What does "Making the subtraction between two dates" mean? Do you want to add or subtract a certain number of days to a date to arrive at a second date? – Basil Bourque Dec 28 '13 at 03:28

6 Answers6

2

If you only want to format the date, Java has built-in formatters for many languages:

final DateFormat formatter = SimpleDateFormat.getDateTimeInstance(
   DateFormat.FULL, DateFormat.FULL,
   Locale.ITALY);
System.out.println(formatter.format(new Date()));  

This prints:

venerdì 2 marzo 2012 22.32.20 CET

Probably you can skip the Locale to use JVM/OS default. Without locale on my computer it prints:

piątek, 2 marzec 2012 22:32:20 CET
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • The problem is that I need also the arithmetic netween two dates: make the difference between two dates, etc ... with DateFormat I can insert in a date 90/90/90 and it's considered right. – Ramy Al Zuhouri Mar 03 '12 at 11:18
2

I would certainly recommend against extending Calendar like this. I would expect you to be able to use SimpleDateFormat (in combination with a Locale) to do all of this without any manual coding. Either specify the format manually or just use DateFormat.FULL to use the locale-specific full date/time format.

My guess is that for whatever reason, your system default time zone isn't coming up properly, which would explain the hour of day issue. Try printing out TimeZone.getDefault().getID() to see what it's using.

As for finding a better API: absolutely, I'd heartily recommend using Joda Time instead of java.util.Date/Calendar. It's a much, much better API. (It's not perfect by any means, but it's better than the built-in classes.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. See Tutorial by Oracle.

This Answer let as-is for history.


a) Verify your computer's clock is set properly. Use something like US government time server, or google "current time".

b) Use Joda-Time.

c) Be explicit about time zones to eliminate confusion due to your own Java environment's defaults. Use time zone names, not 3-letter codes which are neither standard nor unique.

You can create specific formats for rendering strings. But first consider using the built-in formats specific to your locale.

Here is some example Joda-Time code.

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Time Zone list… http://joda-time.sourceforge.net/timezones.html  (not quite up-to-date, read page for details)
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Rome" );

DateTime nowInItaly = new DateTime( timeZone );

DateTimeFormatter formatter = DateTimeFormat.fullDateTime().withLocale( Locale.ITALY );
String dateTimeString = formatter.print( nowInItaly );

Dump to console…

System.out.println( "nowInItaly: " + nowInItaly );
System.out.println( "dateTimeString: " + dateTimeString );

When run…

nowInItaly: 2013-12-28T04:41:19.776+01:00
dateTimeString: sabato 28 dicembre 2013 4.41.19 CET
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

tl;dr

ZonedDateTime.now().plusDays( 10 ).format(
    DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.ITALY )
)

giovedì 15 febbraio 2018 12:35:34 Ora standard del Pacifico USA

java.time

The operations that I need to make are: -Getting the date in string format, translated to Italian; -Making the subtraction between two dates.

Get the current moment for your time zone.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture current moment as seen on wall-clock of people in a particular region.

Generate a String to represent that value, localizing to a particular language and culture. The DateTimeFormatter class can automatically localize when generating a String representing a date-time value.

To localize, specify:

  • FormatStyle to determine how long or abbreviated should the string be.
  • Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

Example:

Locale l = Locale.ITALY ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );

lunedì 5 febbraio 2018 21:28:00 Ora standard dell’Europa centrale

Understand that time zone and locale are orthogonal, completely separate. One defines the meaning of the date-time, the other the presentation.

Date-time math

Represent a span of time unattached to the timeline using either Period for years-months-days, or Duration for hours-minutes-seconds.

Period p = Period.ofDays( 10 ) ;  // Ten days.

Do the math by calling minus or plus methods.

ZonedDateTime zdtLater = zdt.plus( p ) ; // Adding ten days later.

You can calculate elapsed time.

Period delta = Period.between( zdt , zdtLater ) ;

Call Period::toString to generate a string in standard ISO 8601 format.

P10D

Legacy code

If you must inter-operate with old code not yet converted to java.time, you may convert using new methods added to the old classes.

The equivalent of GregorianCalendar is ZonedDateTime.

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;  // Convert from legacy class to modern class.

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
  • 303,325
  • 100
  • 852
  • 1,154
0

My strong recomendation is that you must use JodaTime framework:

http://joda-time.sourceforge.net/

The time format

http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html

An locales:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Locale.html

Ernesto Campohermoso
  • 7,213
  • 1
  • 40
  • 51
0

The problem is most likely with the

super(Locale.ITALY)

It will Constructs a GregorianCalendar based on the current time in the "default time zone" with the given locale.

You will most probably need to change the TIMEZONE too.

I would use this one:

GregorianCalendar(TimeZone zone, Locale aLocale)

Reference

S.P.
  • 3,054
  • 1
  • 19
  • 17