GithubHelp home page GithubHelp logo

jodaorg / joda-time Goto Github PK

View Code? Open in Web Editor NEW
5.0K 215.0 965.0 12.62 MB

Joda-Time is the widely used replacement for the Java date and time classes prior to Java SE 8.

Home Page: http://www.joda.org/joda-time/

License: Apache License 2.0

Java 99.69% HTML 0.28% CSS 0.03%
java joda joda-time date-time

joda-time's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

joda-time's Issues

Add `isBeforeOrEqual` and `isEqualOrAfter` to `ReadableInstant`.

The ReadableInstant interface only provides comparison methods representing the mathematical relations <, =, and >.

However, <= and >= are common as well, but they are not available as methods to compare instants with. This leads either to the creation of additional local utility methods (unfavorable), or to less readable, less expressive code like !entity.getCreatedAt().isAfter(today) (where the negation, !, is written far from the call to the method whose result value is to be negated, and thus too easily overlooked).

With the suggested methods, the above code be written more clearly as entity.getCreatedAt().isBeforeOrEqual(today).

Please consider adding those methods. Dealing with date/time is already hard enough ;)

plus / minus to Intervals

I think that the possibility of obtaining, in an easy way, the Interval which results of adding a Duration to a given Interval, would enhance the features of Joda Time.
E.g. right now I have an Interval representing the time for a lecture in an administrative app for a university, so that the following lecture is exactly one week ahead. I would like to obtain the Interval for the following lecture just by writing
firstLectureInterval.plusWeek(1)
Thanks!

Unexpected behavior for DateTimeZone.isLocalDateTimeGap

The time zone is "America/Rio_Branco". I tried LocalDateTime 2:30am, 3:30am, 4:30am of June 24th, 2008, and all of them returned true, meaning the local time was set forward for 3 hours. But according to official record, there should be only 1-hour gap.

NullPointerException on DateTimeZone.getOffset() when using persistent object

Hello,

I am using JodaTime v2.3 in combination with a DB4O object database. I have noticed that when retrieving DateTime objects from the database I get NullPointerExceptions when calling: dateTimeObj.getZone().getOffset(long)

Here's a stacktrace:
Caused by: java.lang.NullPointerException
at java.util.Arrays.binarySearch(Arrays.java:827)
at org.joda.time.tz.DateTimeZoneBuilder$PrecalculatedZone.nextTransition(DateTimeZoneBuilder.java:1574)
at org.joda.time.tz.CachedDateTimeZone.createInfo(CachedDateTimeZone.java:158)
at org.joda.time.tz.CachedDateTimeZone.getInfo(CachedDateTimeZone.java:145)
at org.joda.time.tz.CachedDateTimeZone.getOffset(CachedDateTimeZone.java:103)

I believe this problem also affects JodaTime v2.2.

Best,

Matthias

Allow alternate location for time zone data files

Due to countries changing their time zone rules and having to reassemble joda-time to pick them up, it'd be beneficial to allow a system property to define an alternate location to read the time zone data files. By defining a property such as

-Dorg.joda.time.tz.data=path/to/files

the data files would be read in from the path provided; if no property was declared, it would default to its current behavior of loading the files it compiled when being packaged. This could be used as a stop-gap until a solution described in #17 could be implemented.

DateTimeFormatter does not parse months as described in JavaDocs

According the JavaDocs numbers are parsed this way: "Number: The minimum number of digits. Shorter numbers are zero-padded to this amount."

Consider this code:
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM");
DateTime dt = fmt.parseDateTime("2013-9");

It does not throw an expection, it silently ignores the fact that a padding zero is necessary. Java's SimpleDateFormat at least documents this inconsistency. Anyway, I would expect parsing to work the very same way as formatting a DateTime.

Nanosecond precision

Hello,

In JRuby, we want nanosecond precision in a couple places.

The JVM only provides a millisecond precision wall-clock (but that should change with JSR 310). So of course for now we can only retain nanoseconds that are given by the user.

The logic to handle nanoseconds lives in RubyTime, the class for handling Ruby "Time" objects. I would like to extract it to some DateTime-like class handling nanoseconds (that is an additional int field). DateTime is a final class so it cannot be subclassed. Composition is of course possible but it might hurt a bit performance and it means to write every delegation method.

What would be a good way to add support for nanosecond precision to DateTime according to you?
Do you have plans for doing this in Joda-Time?

Questionable behaviour of GJChronology when dates pass 1BC

I expect the following test to pass:

Chronology chronology = GJChronology.getInstance();

LocalDate start = new LocalDate(2013, 5, 31, chronology);
LocalDate expectedEnd = new LocalDate(-1, 5, 31, chronology); // 1 BC
assertThat(start.minusYears(2013), is(equalTo(expectedEnd)));
assertThat(start.plus(Period.years(-2013)), is(equalTo(expectedEnd)));

The error it gives is:

org.joda.time.IllegalFieldValueException: Value 0 for year is not supported

However, I never provided "0" for the year myself. I thought it was the job of the framework to skip over non-existent year 0 for me to return 1 BC?

Timezone displays incorrect for Germany

joda time displays timezone in numeric format (i.e. "+2:00") for Germany locale, but for Franch or US locale timezone displayed in verbose format (i.e. EET)
Code snippets to reproduce the issue are displayed below.

This is utility method to make pattern for conversion.

    private static String getDateTimePattern(Locale locale) {
        StringBuffer dateTimePattern = new StringBuffer();
        dateTimePattern.append(((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM, locale)).toPattern());
        dateTimePattern.append(" ");
        dateTimePattern.append(((SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.SHORT, locale)).toPattern());
        dateTimePattern.append(" ");
        dateTimePattern.append("z");

        return dateTimePattern.toString();
    }

Snippet to reproduce in JUnit unit test

        Date date = new Date(100000000);
        Style style = Style.DATETIME;
        Locale locale = Locale.GERMANY;// !!!
        TimeZone zone = new SimpleTimeZone(7200000, "Asia/Amman", 2, -1, 5, 86400000, 0, 9, -1, 6, 0, 1, 3600000);
        dtf = DateTimeFormat.forPattern(getDateTimePattern(locale)).withLocale(locale);
        dtf = dtf.withZone(DateTimeZone.forTimeZone(timezone));
        DateTime dt = new DateTime(date);
        assertEquals("02.01.1970 05:46 EET", dt.toString(dtf));

Problems with equals() methods in Chronology classes

Hello I've come across a number of problems related to the equals() methods (or lack thereof) in Chronology classes.

I was comparing 2 DateTime instances which have the same date, time and timezone but still DateTime.equals() returns false.
So I started to investigate...

DateTime.equals is in fact inherited from AbstractInstant. Looking at the docs and code of AbstractInstant.equals() I found out it checks both the milliseconds and the chronology. The millisecond comparison works fine (and returns true for my test data), however the comparison of chronologies does not work as it should.
Even though the Chronology objects of my DateTime objects were both "ISOChronology[Africa/Brazzaville]" (result of toString()) they were not considered equal.

So I dug deeper. In the code of AbstractInstant I saw that the Chronology comparison is performed using FieldUtils.equals(object, object), which in turns calls the object1.equals(object2) -- i.e. the method ISOChronology.equals() is called, which reads as follows:

public boolean equals(Object obj) {
        return super.equals(obj);
    }
  • The direct super class of ISOChronology is AssembledChronology, but that one does not contain an equals() method;
  • The super class of AssembledChronology is BaseChronology, but that one does not contain an equals() method either;
  • The super class of BaseChronology is Chronology, but, you guessed it, that one also lacks an equals() method
  • The super class of Chronology is Object, and there the implementation of equals() defaults to references comparison (i.e.: this == obj)

Hence, when super.equals(obj) is called in ISOChronology none of the chronology fields are compared, and the result is solely based on object comparison. This is clearly a bug I would argue.

Note: You might wonder how I ever got to have 2 instances of ISOChronology for the same timezone. The reason is that I use an object database (DB4O) to store DateTime instances, and sometimes I need to handle finding duplicates cross multiple dumps of the database (containing largely the same data, but stored in different objects).

Question about year 0000 between JDK and JodaTime

Hi,

Quick question about the output I'm seeing and I'm not sure it's a bug or not.

We are using JodaTime to convert our Calendar/Date objects into ISO8601 format to be sent along in a JSON payload.

Things work fine for most normal dates, but our QA team found an interesting issue when they use the year '0000' which is a valid year.

We are seeing that the JodaTime library seems to lose 2 days during the formatting where the JDK SimpleDateFormatters don't.

Is this a bug? Below is the sample code and output.

OUTPUT

JODA: 0000-10-27T12:03:58.000-04:56:02
JAVA: 0001-10-29T12:00:00.000-0500

CODE

public class DateTest {

   // Standard ISO8601 Date format
   private static final String ISO8601 = "yyyy-MM-dd'T'hh:mm:ss.SSSZ";

   /**
    * Test the difference between JODA and JDK date formats when year is 0000
    * @param args
    */
   public static void main(String[] args) {

      // Set the calendar to known state
      Calendar c = Calendar.getInstance();
      c.set(Calendar.YEAR, 0000);
      c.set(Calendar.DAY_OF_MONTH, 29);
      c.set(Calendar.MONTH, Calendar.OCTOBER);
      c.set(Calendar.HOUR_OF_DAY, 12);
      c.set(Calendar.MINUTE, 0);
      c.set(Calendar.SECOND, 0);
      c.set(Calendar.MILLISECOND, 0);

      Date d = c.getTime();
      doJoda(d);
      doJava(d);

   }

   /**
    * Print using JODA TIME
    * @param d
    */
   private static void doJoda(Date d) {
      System.out.println("JODA: " + new DateTime(d).toString());
   }

   /**
    * Print using JDK
    * @param d
    */
   private static void doJava(Date d) {
      SimpleDateFormat df = new SimpleDateFormat(ISO8601);
      System.out.println("JAVA: " + df.format(d));
   }
}

Thanks...

DateTimeZone.getDefault() returning incorrect value

Cross post from: https://sourceforge.net/p/joda-time/bugs/173/

I created a simple program to display the timezone and the output of this program is incorrect in the Asia/Riyadh timezone. It returns +03:00 as the output when I run this in the Asia/Riyadh domain, but it returns "America/Chicago" when I run it on the normal US domain.

import org.joda.time.DateTimeZone;
public class timezoneclass {
public static void main(String args[])
{
System.out.println(DateTimeZone.getDefault());
}

}

OUTPUT:
+03:00

Any idea why its returning this value? I checked the user.system timezone and the JDK timezone. They look right. I didn't notice any differences between the two domains other than that they are physically in different timezones.

I am using joda-time-1.6.2.jar. I've also tried using the joda-time-2.1.jar but still the same issue. I am trying to understand where it is getting the +03:00 value from. I also checked the TZ variable and it is set to 'WAT-3'. I've changed this to 'WAT-4' but I still get a +03:00 as the output.

Is there anything else I should be looking for? Please advise!

Thank you,
Manogna

Also allow a space as a delimiter between date and time

The most common format for ISO8601 for a timestamp is this

yyyy-mm-ddTHH:MM:SS.SSS

But also a space is allowed:

yyyy-mm-dd HH:MM:SS.SSS

I would suggest you to allow the construction of a timestamp also out of the second variant. Would you please implement this for the constructor DateTime(Object instant)?

I think, that this could be easily done by adding a line like this

((String) instant).replace(' ', 'T');

addDays(0) changes value of MutableDateTime

Upon DST transition from summer to winter time zone, adding the amount of zero days to a mutable date time object changes the value of the object.

The code

final MutableDateTime mdt = new MutableDateTime(2011, 10, 30, 3, 0, 0, 0, DateTimeZone.forID("Europe/Berlin"));
System.out.println("Start date:   " + mdt + " (" + mdt.toInstant().getMillis() + ")");
mdt.addHours(-1);
System.out.println("addHours(-1): " + mdt + " (" + mdt.toInstant().getMillis() + ")");
mdt.addHours(0);
System.out.println("addHours(0):  " + mdt + " (" + mdt.toInstant().getMillis() + ")");
mdt.addDays(0);
System.out.println("addDays(0):   " + mdt + " (" + mdt.toInstant().getMillis() + ")");

prints

Start date:   2011-10-30T03:00:00.000+01:00 (1319940000000)    //OK
addHours(-1): 2011-10-30T02:00:00.000+01:00 (1319936400000)    //OK
addHours(0):  2011-10-30T02:00:00.000+01:00 (1319936400000)    //OK, no change in time
addDays(0):   2011-10-30T02:00:00.000+02:00 (1319932800000)    //error, time has changed by 1 hour

The methods addMonths and addYears show the same problem; addSeconds, addMinutes and addHours are ok.

I have tested with version 2.3. However, if I repeat the test with Joda 1.5.2, the invocation of addDays(0) does not change the date's value.

DateTimeFormat pattern documentation for "S"

In the DateTimeFormat documentation, the symbol S is described as a number, and number's have the following description: "The minimum number of digits. Shorter numbers are zero-padded to this amount.".

However, S doesn't adhere to this description, for example:

DateTimeFormatter format = DateTimeFormat.forPattern("S")
format.parseDateTime("1") # All is well
format.parseDateTime("12") # IllegalArgumentException: Invalid format

S actually represents the exact number of digits, not the minimum.

I suggest adding a new presentation to the documentation in DateTimeFormat with a description that matches the behaviour of S. I think this is the right behaviour for S, and the documentation just needs updating but I thought I should double check before raising a pull request. If it's the expected behaviour I'll submit a PR with a change to the docs :)

DateTimeFormat.parseInto sometimes miscalculates year (2.2)

There appears to be a bug in the fix to http://sourceforge.net/p/joda-time/bugs/148 (which I also reported).

The following code (which can be added to org.joda.time.format.TestDateTimeFormatter) breaks, because the input mutable date time's millis appear to be mishandled and the year for the parse is changed to 1999:

    public void testParseInto_monthDay_feb29_startOfYear() {
        DateTimeFormatter f = DateTimeFormat.forPattern("M d").withLocale(Locale.UK);
        MutableDateTime result = new MutableDateTime(2000, 1, 1, 0, 0, 0, 0, NEWYORK);
        assertEquals(4, f.parseInto(result, "2 29", 0));
        assertEquals(new MutableDateTime(2000, 2, 29, 0, 0, 0, 0, NEWYORK), result);
    }

Create option for joda-time to use the time zone information from the JDK

In an enterprise environment where there are many isolated applications that utilize joda-time, updating the version of joda-time in each application can be time-consuming and could be considered bad practice to change a deployed application. With the availability of the tzupdater utility [1] for Sun/Oracle JREs, updating the time zone recognized by the JRE has become a fairly trivial, one step process (per JRE). It would be beneficial to have an option for joda-time to use the time zone information provided by the JRE.

With the understanding that joda-time was written prior to the availability of the tzupdater and the fact that the tzupdater may be an enterprise-level solution, I would envision this enhancement as an optional feature that can be turned on (or off) as needed.

[1] - http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html

DateTimeComparator doesn't work as expected for dates in different timezone

Using joda-time 2.3 comparing two dates in different timezones is not working as expected. I would expect that if I send in two instances which when passed to the same timezone are on the same day the comparator will say they are on the same day. This is not the case, see small example below.
Even comparing the same instances in time, just in a different timezone (and even on the same day in their respective timezone) is failing.
The current behaviour is not documenting the problem of different timezones.

DateTimeZone HONG_KONG_TZ = DateTimeZone.forID("Asia/Hong_Kong");
DateTime date1 = new DateTime(2013, 10, 2, 11, 30, 53, 512, HONG_KONG_TZ)
DateTime date2 = date1.toDateTime(DateTimeZone.UTC)

DateTimeComparator.getDateOnlyInstance().compare(date1, date2)

The result is not 0 as you would expect, but -1. Calling the comparator with date2.toDateTime(HONG_KONG_TZ) correctly returns 0.

Parsing hour of halfday with LenientChronology yields wrong value

Using a LenientChronology when parsing a time using 12-hour format yields a result in which the am/pm are flipped. On inspection, the issue is in LenientDateTimeField#set(long,int) where the delta between the current and desired value is being calculated. Because this particular field maps its zero value to 12, this ends up generating an incorrect delta, shifting results by 12 hours.

This can be reproduced with the following test:

public void lenientHourOfHalfDay() {
    Chronology utc= ISOChronology.getInstanceUTC();
    DateTimeFormatter format= DateTimeFormat.forPattern("h:mm a").withChronology(utc);

    String text= "3:30 am";
    DateTime result= format.parseDateTime(text);
    DateTime lenientResult= format.withChronology(LenientChronology.getInstance(utc)).parseDateTime(text);

    LocalTime expected= new LocalTime(3, 30);

    // Works, as expected
    Assert.assertEquals("Strict parse result wrong", expected, result.toLocalTime());
    // Fails unexpectedly; value shifted by 12 hours
    Assert.assertEquals("Lenient parse result wrong", expected, lenientResult.withChronology(utc).toLocalTime());
}

More arithmetic for Durations

I would like to have support for the following operations on Duration:

  • Duration.scale(double factor) - stretch the duration by the given factor
    • maybe mul(int factor) and div(int factor) would also make sense
  • Duration.floor(ReadableDuration precision) - round the duration down to the nearest multiple of precision
  • Duration.ceil(ReadableDuration precision) - round the duration up to the nearest multiple of precision

If no one objects to such operations, I would be happy to fork and implement them.

java.io.NotSerializableException after using dateTime.toDate()

Hi,

In order to save the current state in an android application, a java.util.Date object is created from a DateTime object using toDate(). However it seems that the resulting Date object is not properly serializable any more.

We use joda-time 2.2.

outState.putSerializable(ARG_SELECTED_DATE, selectedDate.toDate());
...
DateTime selectedDate = new DateTime(savedInstanceState.getSerializable(ARG_SELECTED_DATE));
Exception
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = org.joda.time.DateTime)
at android.os.Parcel.writeSerializable(Parcel.java:1279)
at android.os.Parcel.writeValue(Parcel.java:1233)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1627)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:132)
at android.os.Parcel.writeTypedArray(Parcel.java:1102)
at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:357)
at android.os.Parcel.writeParcelable(Parcel.java:1254)
at android.os.Parcel.writeValue(Parcel.java:1173)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1627)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2252)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3052)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.io.NotSerializableException: org.joda.time.tz.CachedDateTimeZone$Info
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeNewArray(ObjectOutputStream.java:1205)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1662)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at android.os.Parcel.writeSerializable(Parcel.java:1274)
... 23 more

ISODateTimeFormat.dateTimeNoMillis.print(LocalDate) produces strange characters

Hi.

Joda version 2.1

For reasons too weird to describe, I tried to format a LocalDate using ISODateTimeFormat.dateTimeNoMillis. The date part comes out fine, as does the subsequent 'T'. However, the time parts are rendered not as 00:00:00, but with some strange characters. It's easy to reproduce. Something like:

ISODateTimeFormat.dateTimeNoMillis.print(LocalDate.now())

should show the problem.

appendOptional and Both printing and parsing not supported

I have problem with DateTimeFormatterBuilder.
In Joda 2.1 this code is working without any problem:

DateTimeFormatterBuilder a = new DateTimeFormatterBuilder();
a.append(DateTimeFormat.forPattern("HH:mm"));
a.appendOptional(DateTimeFormat.forPattern(":ss").getParser());
a.appendOptional(DateTimeFormat.forPattern(".SSS").getParser());
a.append(DateTimeFormat.forPattern(":ss.SSS").getPrinter());
DateTimeFormatter f = a.toFormatter(); 
DateTime c = f.parseDateTime("05:04:59");
System.out.println(f.print(c));

But it does not work anymore in newer versions. I tried versions 2.2 and 2.3.
a.toFormatter() raises exception:
Both printing and parsing not supported

The problem occurs only when appendOptional method is used.

What was changed that it stopped working?

Thank you for your help.

ISODateTimeFormat thread safety

(as per discussion on the joda-interest list)

The javadoc of ISODateTimeFormat class says it's thread-safe and immutable. The static fields are lazily initialized. However it seems it's not done in a thread-safe manner.

For example, dt is lazily initialized in
public static DateTimeFormatter dateTime() {
if (dt == null) {
dt = new DateTimeFormatterBuilder()
.append(date())
.append(tTime())
.toFormatter();
}
return dt;
}

When there are two threads both inside this method, is it possible that one thread sees an unsafely published non-null dt value due to cache incoherence?

LocalDate hashcode implementation

Hi, I have noticed that the hashcode for LocalDate is cached in:

/** The cached hash code. */
private transient volatile int iHash;

this code does not need to be volatile, volatile introduces uneeded overhead every time hascode is invoked.

if this field is not volatile the hashcode will be computed in the worst case scenario more than once, but I believe this is a more acceptable approach.

String hashcode caching is implemented whithoud a volatile field as well...

DST settings seems to be interpreted incorrectly when using custom time zone

private static final Logger logger = LoggerFactory.getLogger(JodaTimeZoneTest.class);

private static final LocalDateTime SUMMER_TIME = LocalDateTime.parse("2013-06-25T12:00:00");
private static final LocalDateTime WINTER_TIME = LocalDateTime.parse("2012-12-25T12:00:00");

public void testTimeZone(TimeZone tz) {
        DateTimeZone dtzone = DateTimeZone.forTimeZone(tz);
        int winterHours = hourOfDayUTC(WINTER_TIME, dtzone);
        int summerHours = hourOfDayUTC(SUMMER_TIME, dtzone);
        logger.info("TZ: {}, winter hours={}, summer hours={}", new Object[]{tz, winterHours, summerHours});
        assertEquals(1, Math.abs(winterHours - summerHours));
    }

    private int hourOfDayUTC(LocalDateTime winterTime, DateTimeZone dtzone) {
        return winterTime.toDateTime(dtzone).toDateTime(DateTimeZone.UTC).getHourOfDay();
    }

passes for TimeZone.getTimeZone("Europe/London") but fails for custom TZ with the same settings:

new SimpleTimeZone(3600000,
                "GMT",
                Calendar.MARCH, -1, Calendar.SUNDAY,
                3600000, SimpleTimeZone.UTC_TIME,
                Calendar.OCTOBER, -1, Calendar.SUNDAY,
                3600000, SimpleTimeZone.UTC_TIME,
                3600000) 

Period constructor always zero, print then parse a period gives different period and zero period not equal

Hi I wanted to let you know that the following code has 3 issues:

Period p1 = new Period(5L, PeriodType.hours());

String string = p1.toString();
System.out.println(string);     

Period p2 = Period.parse(string);
System.out.println(p2);

//The expected result
Period period=Period.hours(5);
System.out.println(period);

assert p1.equals(p2);

Outputs:
PT0H
PT0S
PT5H
Exception in thread "main" java.lang.AssertionError

  1. It seems that the Period constructor is broken.

  2. One would expect that printing a period and then parsing it would give an identical period.

  3. One would expect that a zero period in hours should be equal to zero seconds.

Release Joda Time 2.2

joda-time joda-time 2.2

DateTimeFormatter parsing issues with patterns "EEE MMM dd HH:mm:ss yyyy" and "EEE MMM dd HH:mm:ss ZZZ yyyy"

Hi,

I have seen a weird issue with DateTimeFormatter lately, and after some googling without anything similar, I think it might be a bug in the parsing logic of joda-time 2.2 and 2.1.
For example, the below code...

String text = "Tue Aug 11 21:41:19 2013";
DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss yyyy");
DateTime dateTime = formatter.parseDateTime(text);
assertThat(formatter.print(dateTime), is(text));

... fails with:

java.lang.AssertionError: 
Expected: is "Tue Aug 11 21:41:19 2013"
    but: was "Tue Aug 06 21:41:19 2013"

If you debug this, you will see that parseDateTime somehow transforms 11th of August into the 6th of August.
Besides the same happens with the pattern: "EEE MMM dd HH:mm:ss ZZZ yyyy" and strings like: "Tue Aug 11 21:41:19 Europe/London 2013".

Would you be able to:

  • confirm it is a new bug and not a known issue?
  • advise about the next steps?

I am happy to try to provide a patch if you point me to the right direction (where is what, etc.).

Cheers,

M.

JPA support?

Hi, I would to use Joda Time, but I prefer to not jump JPA to hibernate direclty.
So exist the chance to have the support for JPA in the next future?

Thanks

JodaTime incorrectly converts some time zones on JDK 1.6

The Joda Time 2.3 incorrectly converts MST TimeZone to DateTimeZone. The following test fails:

    @Test
    public void test() {
        TimeZone jdkMST = TimeZone.getTimeZone("MST");
        DateTimeZone mst = DateTimeZone.forTimeZone(jdkMST);
        DateTimeZone mst2 = DateTimeZone.forID(jdkMST.getID());
        assertEquals("MST", mst2.getID());
        assertEquals("MST", mst.getID());
        assertEquals(mst, mst2);
    }

The resulting zone for MST is "America/Denver" that has daylight saving, while MST does not have daylight savings. This causes incorrect display of the time, since time zone offset of different.

Apparently the offending method is in DateTimeZone.java:

    private static synchronized String getConvertedId(String id) {
        Map<String, String> map = cZoneIdConversion;
        if (map == null) {
            // Backwards compatibility with TimeZone.
            map = new HashMap<String, String>();
            ......
            map.put("MST", "America/Denver");  // JDK 1.1 compatible
            ......
            cZoneIdConversion = map;
        }
        return map.get(id);
    }

It possibly contains some work around for JDK 1.1, but this workaround also applies to JDK 1.6, that contains correct definition of MST time zone. JDK 1.1 work around should be applied only when needed and not to change DateTimeZone when it is not needed.

copy/clone

What's the point of (MutableDateTime|MutableInterval|MutablePeriod) copy methods? Why not just have clone return the specific class in question rather than Object?

Migration to JUnit4

It could be a nice idea to migrate JUnit to the 4 version. It contains a lot of nice features like annotations, parameterized tests, matchers and so on

Days#daysBetween throw exception for MonthDay with 29 February

final LocalDate january12012 = new LocalDate(2012, 1,1);
final LocalDate february292012 = new LocalDate(2012, 2, 29);
// OK
assertEquals(59, Days.daysBetween(january12012, february292012).getDays());

final MonthDay january1 = new MonthDay(1,1);
final MonthDay february29 = new MonthDay(2, 29);
// FAIL
assertEquals(59, Days.daysBetween(january1, february29).getDays());

org.joda.time.IllegalFieldValueException: Value 29 for dayOfMonth must be in the range [1,28]
at org.joda.time.field.FieldUtils.verifyValueBounds(FieldUtils.java:217)
at org.joda.time.field.PreciseDurationDateTimeField.set(PreciseDurationDateTimeField.java:78)
at org.joda.time.chrono.BaseChronology.set(BaseChronology.java:240)
at org.joda.time.base.BaseSingleFieldPeriod.between(BaseSingleFieldPeriod.java:103)
at org.joda.time.Days.daysBetween(Days.java:141)

Is there a way to avoid this happening? I understand fiddling around with the leap year, you're bound to get issues.

Thanks!

Interval equals javadoc is wrong

currently the equals javadoc says

Returns:
true if the start and end millis are equal

this is not correct, it also compares the chronology. I know it mentions it just above, but I think the return comment should be updated as well.

Also, it would be nice if there was an isEqual method, similar to the one for AbstractInstant

Currently the only way I have found to do this check is something like

return interval1.getStart().isEqual(interval2.getStart()) && interval1.getEnd().isEqual(interval2.getEnd());

DateTime API using minus and plus APIs

Hi!

I am running into an issue that just started this month. Here is come sample code:

DateTime now = new DateTime();
now = now.minusMonths(11);
now = now.minusWeeks(3);
now = now.plusMonths(11);
System.out.println(Weeks.weeksBetween(now, new DateTime()).getWeeks());

weeksBetween will return 2 instead of 3. Anyone know why this is occurring? I am using 2.2 version of the API.

Thanks!

ReadableInstant extends Comparable and not Comparable<ReadableInstant>, but the implementation behaves as the latter

Let me start with code (I used Date as a comparison, but anything comparable would do, like String, Integer, ...):

java.util.Date normalDate = new java.util.Date();
org.joda.time.DateTime jodaDate = new new org.joda.time.DateTime();
org.junit.Assert.assertThat(normalDate, org.hamcrest.Matchers.equalsTo(normalDate));
org.junit.Assert.assertThat(jodaDate, org.hamcrest.Matchers.equalsTo(jodaDate));
org.junit.Assert.assertThat(normalDate, org.hamcrest.Matchers.lessThan(normalDate));
org.junit.Assert.assertThat(jodaDate, org.hamcrest.Matchers.lessThan(jodaDate));

at the 4th assertThat (jodaDate/lessThan) I get weird warning message in Eclipse:

Type safety: The expression of type Matcher needs unchecked conversion to conform to Matcher<? super DateTime>

My guess it is because ReadableInstant extends Comparable and not Comparable<ReadableInstant>.
int compareTo(Object readableInstant); will throw a ClassCastException if it's not instanceof ReadableInstant which makes it pointless to implement the raw Comparable interface.

That check can be made by the compiler at compile time. In my opinion it won't break any working code because if someone ever calls it with anything other than ReadableInstant instance, they would get an exception anyway, which no-one wants I guess (maybe your unit tests...).

Would it be possible to change the interface extension to the generic one?
It will give a warning for anyone who tries to use it against any generic interface which expects Comparable, which is pretty annoying if they want "warning-less" code. @SuppressWarnings is rather pointless, hopefully I'll only have to use it at a few places. (For example equalsTo in Hamcrest does not give a warning)

Migrated from https://sourceforge.net/p/joda-time/bugs/172/

LocalDate.toInterval(DateTimeZone) returns unexpected interval on Day Light Saving cut over day

Repro:

DateTimeZone = DateTimeZone.forID("America/Havana");
long milli = 1352005199998;
MutableDateTime dt = new MutableDateTime(milli, timeZone);
// now dt is 2012-11-04T00:59:59.998-04:00

int year = dt.getYear(); // 2012
int month = dt.getMonthOfYear(); // 11
int day = dt.getDayOfMonth(); // 4

Interval theDay = new LocalDate(year, month, day).toInterval(timeZone);
// theDay is 2012-11-04T00:00:00.000-05:00/2012-11-05T00:00:00.000-05:00,
// which does not include dt.

Interval lastDay = new LocalDate(year, month, day-1).toInterval(timeZone);
// lastDay is 2012-11-03T00:00:00.000-04:00/2012-11-04T00:00:00.000-05:00
// i.e. joda thinks that 2012-11-04T00:59:59.998-04:00 is an instance of 2012-11-3
// instead of 2012-11-04

Strange behavior with february when calculate period and espessially the month calculation

about the february month there is a strange behavior that you can see in the incorect results with jodatime, you can look down here :

        DateTime date4 = new DateTime(2013, 5, 29, 0, 0, 0, 0);
        DateTime date4PlusNineMonths = new DateTime(2014, 2, 28, 0, 0, 0, 0);
        Period period4 = new Period(date4, date4PlusNineMonths);
        //Incorrect result
        System.out.print(date4.toString("dd/MM/YYYY")+".plusMonths(9) = "+ date4.plusMonths(9).toString("dd/MM/YYYY"));
        System.out.print(period4.getYears() +"Years/"+ period4.getMonths() +"Months/"+ period4.getWeeks() +"Weeks/"+ period4.getDays() +"Days");

Output :
29/05/2013.plusMonths(9) = 28/02/2014 //incorrect result should be 01/03/2014
0Years/9Months/0Weeks/0Days

This is an incorrect calculation It should be 0Years/8Months/4Weeks/2Days Isn't it...?

If it is correct so why when I increase two days more (30 and 31) it always give me the same calculation (0Years/9Months/0Weeks/0Days) we all agree that days are really decreasing or am I dreaming...?

Now maybe I wrong in my use of the joda framework because in the app I develop I do a check everyday on a period to have the precise month separation between two date (toDay and the next date) and if I have 9months and 1day it's too late I need to have 9months and 0days as required in my app =/

If I wrong how can I achieve this please...?

Release notes are nowhere to be found / dead link

I wanted to browse the release notes for the latest releases, since I missed the last updates. I had a bad time finding the release notes in the first place, and then I found myself going through the commits of https://github.com/JodaOrg/joda-time/blob/master/RELEASE-NOTES.txt. I don't think this is intended.

  • The main page contains a dead link.
  • The main website doesn't even bother to mention the release notes exist anywhere (how about the download page?).

Regards,
Benjamin

NPE in DateTimeZoneBuilder

When a DateTimeZone is build with duplicate-named 'recurring saving time' in a first thread, all goes Ok: a warning message is generated and an identifier is automatically generated in PrecalculatedZone.create(). When a second thread does the same, an NPE is generated in ZoneInfoCompiler.verbose().

The cause is that the cVerbose ThreadLocal is incorrectly initialized in ZoneInfoCompiler:

   static {
        cVerbose.set(Boolean.FALSE);
    }

...will initialize cVerbose only for the first thread and not for the subsequent ones. The NPE is caused by the autoboxing in:

   public static boolean verbose() {
        return cVerbose.get();
    }

A better approach could be to remove the initialization and test for null:

public static boolean verbose(){
    Boolean verbose = cVerbose.get();
    return (verbose != null) ? verbose : false;
}

Here follows a test case:

    @Test
    public void testDateTimeZoneBuilder() throws Exception {
        getTestDataTimeZoneBuilder().toDateTimeZone("TestDTZ1", true);
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                getTestDataTimeZoneBuilder().toDateTimeZone("TestDTZ2", true);
            }
        });
        t.start();
        t.join();
    }

    private DateTimeZoneBuilder getTestDataTimeZoneBuilder() {
         return new DateTimeZoneBuilder()
         .addCutover(1601, 'w', 1, 1, 1, false, 7200000)
         .setStandardOffset(3600000)
         .addRecurringSavings("", 3600000, 1601, Integer.MAX_VALUE, 'w', 3, -1, 1, false, 7200000)
         .addRecurringSavings("", 0, 1601, Integer.MAX_VALUE, 'w', 10, -1, 1, false, 10800000);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.