Showing posts with label joda. Show all posts
Showing posts with label joda. Show all posts

Wednesday, 9 January 2019

Commercial support for Joda and ThreeTen projects

The Java ecosystem is made up of many individuals, organisations and companies producing many different libraries. Some of the largest projects have long had support options where users of the project, typically corporates, can pay for an enhanced warranty, guaranteed approach to bug fixes and more.

Small projects, run by a single individual or a team, have been unable to offer this service, even if they wanted to. In addition, there is a more subtle problem. The amount a small project could charge is too low for a corporate to pay.

This sounds odd, but was brought home to me by this thread on twitter:

As the thread indicates, it is basically impossible for a corporate to gift money to a small project, and it is not viable for small projects to meaningfully offer a support contract.

The problem is that not paying the maintainers has negative consequences. Take the recent case where a developer handed his open source project on to another person, who then used it to steal bitcoins.

Pay the maintainers

I believe there is now a solution to the problem. Tidelift.

Tidelift offers companies a monthly subscription to support their open source usage. And they pay some of that income directly to the maintainers of the projects that the company uses.

Maintainers are expected to continue maintaining the project, follow a responsible disclosure process for security issues and check their licensing. Tidelift does not get to control the project roadmap, and maintainers do not have to provide an active helpdesk or consulting. See here for more details.

As such, I'm now offering commercial support for Joda-Time, Joda-Money, Joda-Beans, Joda-Convert, Joda-Collect, ThreeTen-Extra, ThreeTen-backport via the Tidelift subscription.

This is an extra option for those that want to support the maintainers of open source but haven't been able to find a way to do so until now. The Joda and ThreeTen projects will always be free and available under a permissive licence, so there is no need to worry as a result of this.

Comments welcome.

Monday, 1 August 2011

Joda-Time v2.0

Joda-Time version 2.0 is now released! Download. Release notes.

Firstly, Joda-Time 2.0 is NOT a re-write of Joda-Time. The major version number change signifies that there are some incompatibilities. However, these are as minor as I could make them.

A few methods on Chronology that were deprecated for years have been removed, but most other deprecated and classes methods remain as the benefits of removing them were lower than the damage caused.

The library has moved to JDK 1.5 compatibility, adding generics. Sadly, adding generics to Comparable in some cases caused issues for implementations. The choice was to aim for binary incompatibility at the expense of source incompatibility if the ReadableInstant or ReadableDuration interfaces were implemented directly. If you didn't implement these, or extended the supplied abstract class then you should have no problems. Similarly, ReadablePartial had Comparable added, but if you didn't implement it, or extended the supplied abstract class then again you should have no problems.

In summary, I hope there are no significant binary incompatibilities. If you do find a binary incompatibility that I didn't, I'd like to know, particularly if it affects another open source project. If it is in the next week or so, then perhaps the incompatibilty can be fixed and "jar hell" avoided.

There are a number of semantic changes as well in the corner cases. Again see the release notes.

  • Parsing a month-day without a year now selects year 2000 rather than 1970 (so the 29th of February can be parsed)
  • Edge cases with a week-based-year and a month are handled better
  • Methods that handle daylight savings time (DST) are more consistent, retaining the offset wherever possible during calculations or consistently choosing summer time if not
  • Some short time zone IDs have been changed
  • DateTimeZone factory taking an ID is now case sensitive

And of course there are some enhancements:

  • Static factories now() and parse() added to the main date-time classes
  • New classes YearMonth and MonthDay
  • API added to plugin to the Joda-Time clock
  • Period formatting in multiple langauges
  • Parsing of LocalDate/LocalTime/LocalDateTime directly supported (much better than previously)
  • Parsing of time-zone IDs and some support for parsing time-zone names (via the builder)
  • Better handling of 'Z' when parsing to mean +00:00
  • Reliable way to get the start of day for a DateTime - withStartOfDay()
  • Convenient way to handle DST, DateTime.withEarlierOffsetAtOverlap() .withLaterOffsetAtOverlap()
  • Provide direct conversion from LocalDate and LocalDateTime to java.util.Date
  • More constructors and methods for Duration
  • More constructors for DateTime
  • Support JDK 1.6 pluggable resource providers
  • More compatible with the Java Memory Model in JDK 1.5 and higher
  • Added support for Joda-Convert without adding a dependency

Hopefully, you can just drop Joda-Time into your application and you will not notice any change. However, you should definitely read the release notes first.

Finally, as I'm sure someone will ask, this doesn't affect ThreeTen/JSR-310. This release was necessary to finally release a lot of bugs and enhancements in Joda-Time.

PS. As a bonus, there is a re-release of the JSP tags library, as apparantly it wasn't in maven central correctly up until now.

PPS. For Hibernate 4.0 support, please use the usertype project.

Sunday, 29 May 2011

Beans and properties

A few words on beans and properties in Java, prompted by the JavaFX 2.0 API and my work on Joda-Beans.

Beans and Properties

I was prompted to write this by the new API of JavaFX 2.0. It has a new extension to JavaBeans that adds support for properties, so that the JavaFX GUI can bind one property to another. I've been writing property extensions to JavaBeans for over 12 years now, so I feel I should comment on the design.

The basic design approach is to have an object representing each property on a bean. This object allows meta-data attributes to be stored per property (useful for marking errors), property change listeners (for GUIs) and tool access without reflection (allowing XML input/output, XPath, JSON etc).

The basic design adds an additional method to the JavaBean pattern. Alongside getSurname() and setSurname() there would be the property method surname(). This would return a Property object, which supports querying and setting the value, checking whether it was read-only or read-write, finding its type and adding property change listeners.

// basic querying via JavaBeans or property
  String surname = person.getSurname();
  String surname = person.surname().get();
  
  // additional features available with properties
  Property<String> property1 = person.surname();
  Property<String> property2 = person.property("surname");
  Map<String, Property<?>> propertyMap = person.propertyMap();
  person.surname().setAttribute("error", "MANDATORY");
  person.surname().addListener(...);

All the versions of this I've written follow a pattern relatively similar to that above. And the JavaFX 2.0 design is remarkably similar to this. However, some implementations of the pattern are more successful than others.

Version 1 - Original Joda

My initial work in the area was private, but I wrote a variation in open source around 2000 (unmaintained from 2002). This was the first Joda project (before Joda-Time), and still lives on the web here (Javadoc). Here is the original Joda approach (shown with generics for clarity):

public interface Person {
    Property<String> surname();
    String getSurname();
    void setSurname(String surname);
  }

In that project, the class was created using a Proxy object. Clearly, this approach was rather limiting, as a factory had to be used to created an instance of a bean. For various reasons, including the factories, this version was abandoned.

Version 2 - Instantiated Property objects

This version existed at one of my old day jobs. It used code generation rather than Proxy, which was better. However, it used this approach to the beans:

public class Person extends Bean {
    private final Property<String> surname = new Property(String.class);  // object created when person created
 
    public Property<String> surname() { return surname; }
    public String getSurname() { return (Strung) surname.get(); }     // state held on the property
    public void setSurname(String surname) { surname.set(surname); }
  }

Note that every time a Person is created, a Property object is created. Now imagine what happens when you have 20 properties on the bean - thats 21 object creations for an empty Person! And 21 garbage collections! It turns out that this design works OK for client side work, where there is a single machine and processing is limited by what one human can do. However, on the server side it performs horribly. Thus, it got converted into version 3.

Version 3 - Data on the bean

The version 2 approach stored all the state on the Property, but this approach does not work well with the JVM (it could, if the JVM/Java had the ability to inline the state of immediate child objects into the state of the parent object). Thus, the next approach was to move all the state from the property to the bean:

public class Bean {
    private final Map<String, String> attributes;
  }
  public class Person extends Bean {
    private final String surname;
 
    // code generated:
    public Property surname() { return new Property<String>(this, "surname"); }
    public String getSurname() { return surname; }
    public void setSurname(String surname) { this.surname = surname; }
 
    protected Object propertyGet(String propertyName) {
      switch (propertyName.hashCode()) {
        case 36527358: return getSurname();  // number is "surname".hashCode()
      }
      return null;
    }
  }

This approach moves all the state from the property back to the bean itself. The superclass would store any common items, like the attribute map (for error code) or the listeners, while the main person class stores the data using normal fields. The code generation adds a method that connects up the field without reflection.

Since the property is esentially stateless, it can be created on demand, used and then discarded. Short lived objects like that are good for the garbage collector, so long as they are not used too frequently. This design was successful on the server side, and supported all the other goodies, like conversion to and from XML and XPath searching, all without reflection. I believe that a dynamic code generation approach would also work, but the static code generation was effective enough that we didn't go further.

Version 4 - Joda-Beans (the next generation...)

The new Joda-Beans project (Javadoc) is an open source version of the version 3 approach, written from the ground up, but focussed on the essential elements for simplicity. It is currently in use at OpenGamma.

Again, a code generator is used to create the getters, setters and property methods, plus the supporting methods like propertyGet() and propertySet(). This time however, there is a greater focus on the meta-property level, which is the representation of the surname property as a concept, rather than tied to a particular bean instance. Think of the relationship between a property and a meta-property as similar to the relationship between an object and a class. (Effectively, Joda-beans defines both type 1 and type 2 properties.)

Rather than show a code sample here, I encourage you to look at some example classes to see what the code generator produces: Person, Address and the subclass CompanyAddress. The developer only writes the part outside the "code generated" block. The block is generated and re-generated without destroying any additional methods that are hand-written, so you can treat it as a "normal" class in all other ways.

Once again, the property objects hold no long-lived state and are created on demand. After 12 years of working with properties, I'm convinced that is the only design that scales acceptably for the server side on the JVM.

While the Joda-Beans project is not at v1.0 yet, it does work and enhances coding in Java. I'd love to have some early adopters try it out!

JavaFX 2.0

The JavaFX 2.0 approach uses stateful properties (Javadoc - javafx.beans packages). As I've discussed above, such an approach is powerful and conceptually simple, but has performance issues on anything other than the client side. Some articles on the JavaFX 2.0 approach are here and here Clearly, a major concern of the design is listeners, but I still have concerns about this approach.

Other implementations

There are other projects too that have tackled this problem, including Proper properties, Bean-properties, Better beans binding, and Remi's compiler changes (I'll add anything in the comments to this list). No project has won a large mind share though, and most seem unmaintained. A related solution is the ugly JPA typesafe extension.

Language solutions

I've said this before and I'll say it again. The lack of properties in Java is the biggest missing langauge feature and the amount of wasted development time globally by developers writing beans or tools to access properties is gigantic. Moreover, I believe that adding properties to Java is more important than both generics and closures, and should have been prioritised accordingly. (Every enterprise developer knows how much they use the broken JavaBean approach.)

The new JVM languages all have properties (no surprise there), although not all have proper support for obtaining an object to represent the property. Maybe one day, Java itself will support properties as a language feature, it is being vaguely mentioned now, but I'm not holding my breath.

Summary

Properties are a hugely beneficial language feature and raise the abstraction level of coding. While the Java language continues to not have them, you can use or help the Joda-Beans project to add them to your codebase.

My experience suggests that the JVM is poor at handling stateful property objects. Unfortunately, this is the route that JavaFX 2.0 has chosen. It might work for them (because they are client side, and because JVMs are getting faster), but I would advise against using JavaFX 2.0 properties on the server side without lots of performance testing.

Feedback welcome...

Tuesday, 7 September 2010

Joda-Convert and Joda-Primitives v1.0

At the weekend I release v1.0 of two projects - Joda-Convert and Joda-Primitives.

Joda-Convert

This is a simple library targetted at converting objects to and from strings. As well as the standard interface plugin point for adding your own converters it has annotation based conversion. This allows you to add the ToString and FromString to methods of your class and have Joda-Convert pick them up.

See the website and previous blog for more details.

Joda-Primitives

This is a library providing collections, iterators and lists based on primitive types rather than objects. Using collections in this way can yield considerable space and performance benefits over boxed primitives.

The project began life a number of years ago as a fork from Commons Primitives. The main difference is that Joda-Primitives extends the original JDK collections interfaces for seamless integration, whereas Commons-Primitives requires wrappers to interoperate.

It is hoped that support for other collection types may be added, however it is not top of my list of things to do.

See the website for more details.

Friday, 20 August 2010

Joda-Convert

Type conversion to and from a String is a very common application problem. To aid in the process, I've created a small library - Joda-Convert.

Joda-Convert

There are many libraries designed for converting from one object to another, so why create another. Well, partly because I wanted something focussed on the task of Object to String rather than the larger problem of Object to Object. See this list (bottom of the page) for other projects.

The second reason I wanted to write Joda-Convert was to experiment with annotation based conversion. This is an extension of the principles in JSR-311 (RESTful API) where type conversion is performed by looking for a valueOf static method or a constructor that takes a String. While this approach is very useful, it doesn't support some of my projects like JSR-310, where the static method is named of or parse.

This leads into the third reason. If the annotation based approach is successful, then Joda-Convert is ideally placed to be moved into the JDK. It would be wonderful to see the JDK classes annotated to indicate which methods should be used to convert to and from String.

Using Joda-Convert is easy:

// conversion to String
String str = StringConvert.INSTANCE.convertToString(foo);

// conversion from String
Foo bar = StringConvert.INSTANCE.convertFromString(Foo.class, str);

There are built in converters for many JDK types. It is also possible to create an instance of StringConvert to allow application converters to be registered.

When searching for a converter, if one is not already registered, then the system will search the class for annotations:

public class Distance {

  @FromString
  public static Distance parse(String str) { ... }

  @ToString
  public String getStandardOutput() { ... }

}

As can be seen, adding the annotations to a class is very simple. The Joda-Convert system will parse the class, find the annotations and create a suitable converter that calls the annotated methods by reflection. The key point is that they can be used on any method, rather than the convention approach used by JSR-311. Consider a class like TimeZone to understand why this is important.

One little known point about annotations is that the annotation class is not needed at runtime. This means that a library like Commons-Lang could add the annotations to their Mutable* classes without actually adding a runtime dependency. If a user chose to not use Joda-Convert then there would be no impact. If a user did choose to use Joda-Convert, then the conversion would just work.

If I can release Joda-Convert soon, then I will add the annotations to Joda-Time and Joda-Money. Hopefully other projects will consider the idea too! (If you're interested, let me know, as it gives an incentive to get the project to v1.0)

Summary

Joda-Convert is currently an untested Alpha that exists to test out the annotation idea (although as far as I know it does work). I'd welcome participants that want to help test and finish the JDK conversions. I'd also like to see 'helper objects' added, so a DateTimeFormatter can be used to help convert a DateTime, or a ClassLoader to convert a Class.

Feedback welcome as always!

Friday, 20 November 2009

Why JSR-310 isn't Joda-Time

One question that has been repeatedly asked is why JSR-310 wasn't simply the same as Joda-Time. I hope to expain some reasons here.

Joda-Time as JSR-310?

At its heart, JSR-310 is an effort to add a quality date and time library to the JDK. So, since most people consider Joda-Time to be a quality library, why not include it directly in the JDK?

Well, there is one key reason - Joda-Time has design flaws.

Now before everyone panics and abuses that line as a tweet, I need to say that Joda-Time is by far the best option curently available, and that most users won't appreciate the design flaws. But, I do want to document them, so the basis for the changes in JSR-310 is clear.

1) Human/Machine timelines

One element of clarity is a better understanding of the distinction between the two principle views of the timeline - Human and Machine.

Machines have one view - a single, ever increasing number. In Java we set zero as 1970-01-01T00:00Z and count in milliseconds from there.

Humans have a totally different view of time. We have multiple calendar systems (one primary, many others), which divide the timeline into years, months, days, hours, minutes and seconds. In addition, humans have time zones which cause the values to vary around the globe, and for there to be gaps and overlaps in the human timeline as DST starts and ends.

Much of the time, a conversion between the two timeline views is possible with a time zone, however in a DST gap or overlap, things are much less clear.

Joda-Time defines two key interfaces - ReadableInstant and ReadablePartial. Both the Instant class (simple instant in time) and the DateTime class (human view of an instant in time) are implementations of ReadableInstant. This is wrong.

DateTime is a human-timeline view of the world, not a machine-timeline view. As such, DateTime is much better thought of, and designed as, a LocalDateTime and a timezone rather than the projection of the machine timeline onto the human timeline. Thus, DateTime should not implement ReadableInstant.

2) Pluggable chronology

What is the range of values returned by this method in Joda-Time?:
int month = dateTime.getMonthOfYear();
The answer is not 1 to 12, but could be 1 to 13! (yet January is still 1 and December is 12)

The answer to this puzzler is down to pluggable chronologies. Each date/time class in Joda-Time has a pluggable chronology. This defines the calendar system that is in use. But most users of the API never check to see if the chronology is the standard ISO/ chronology before calling getMonthOfYear(). Yet, the Coptic chronology has 13 months in a year, and thus can return a range of 1 to 13.

A better solution would be to keep the date/time classes restricted to a single calendar system. That way, the result from each method call is clear, and not dependent on any other state in the class, like the chronology.

3) Nulls

Joda-Time accepts null as a valid value in most of its methods. For date/times it means 1970-01-01T00:00Z. For durations it means zero. For peiods it means zero.

This approach causes random bugs if your code happens to provide a null to Joda-Time that you hadn't originally planned for. Instead of throwing an error, Joda-Time continues, and the resulting date/time is going to be different from what you want.

4) Internal implementation

Certain aspects of the internal implementation are complex, and the result of having pluggable chronologies and a misunderstanding of the machine/human divide in the timeline. Changing this is a big change to the code.

One particular area of trouble is managing DST overlaps. The behaviour in Joda-Time of these isn't that well defined.

Summary

Joda-Time isn't broken!

It does the job it was designed for, and does it much better than the JDK. And it is widely used and without too many major issues. However, after a few years, it is now clear where it could be designed better.

I took the decision that I didn't want to add an API to the JDK that had known design flaws. And the changes required weren't just minor. As a result, JSR-310 started from scratch, but with an API 'inspired by Joda-Time'.

I hope that explains the thought process behind the creation of a new API in JSR-310.

Tuesday, 17 November 2009

Joda-Money 0.5

I've just released v0.5 of Joda-Money. It is a simple money and currency package along the lines of Joda-Time.

Joda-Money 0.5

Joda-Money is a project to provide a small, focussed monetary library for Java, similar to Joda-Time. I released v0.5 this morning.

Website, Javadoc, Download, Maven 2 repo

The code is all tested and there are no known bugs. But I wouldn't suggest using it in production code quite yet. I do want lots of feedback and testing though! So, all feedback is welcomed, here, the forum or the list.

The main API is as I originally intended. There is a Money and BigMoney class, the former decorates the latter to restrict the number of decimal places to the currency scale.

There is also CurrencyUnit and a provided data file of currency data. Finally, there is printing (but not parsing yet).

The goal of the library remains just these basic classes. Financial calculations (for whatever domain) or classes storing specific concepts like gross/net/tax are out of scope for the library.

This release is part of the 'release early' approach. Please provide as much feedback as you can!

Sunday, 23 August 2009

Joda-Money

I've been busy piloting a new open source project - Joda-Money. The idea is a simple money and currency package along the lines of Joda-Time.

Joda-Money

Joda-Money is a new project to try and create a small, focussed monetary library for Java. While there are various libraries that tackle this area, I wanted one that fitted with the Joda-Time style.

So far, I've created a Money and CurrencyUnit class and started on formatting. The goal of the library is only these basic classes. Financial calculations (for whatever domain) or classes storing specific concepts like gross/net/tax are out of scope for the library.

The design is as follows:

Money is the main class, and supports an amount of money with the decimal places determined by the currency. Thus, GBP always has 2 decimal places, while JPY always has 0.

CurrencyUnit is the class representing currency. I debated whether to just use the JDK Currency class, but it doesn't handle currency changes, or provide the numeric code (both being fixed in JDK 7).

MoneyFormatter will provide formatting of Money instances.

BigMoney will be the final class, which will allow any amount of decimal places to be specified for any currency.

This blog is a 'release early' notification. If you like the Javadoc, or think that this is an area that should be tackled, then let me know. If not, then also let me know (I don't want to waste my time...). Lets hear the feedback!

Monday, 29 October 2007

Joda-Time 1.5 released

Finally released today, after a long wait, is Joda-Time version 1.5. This release fixes a number of bugs, and contains a raft of enhancements, which should make it a desirable upgrade for most users.

One enhancement is to provide a way to handle awkward time zones where midnight disappears. In these zones, the daylight savings time (DST) spring cutover results in there being no midnight. Unfortunately, the LocalDate.toDateTimeAtMidnight() method required midnight to exist and throws an exception if it doesn't. Version 1.5 adds a LocalDate.toDateTimeAtStartOfDay() method which handles this case by returning the first valid time on the date.

The Period class has also received a lot of new methods. You can now easily convert to a Duration and other periods using the standard ISO definitions of seconds/minutes/hours/days. You can also normalize using these definitions, converting "1 year 15 months" to "2 years 3 months".

Finally, it is now easier to tell if a given instant is in summer or winter time. This uses the new DateTimeZone.isStandardOffset() method.

Full details are available in the release notes or just go ahead and download! Maven jar, sources and javadoc are also available.

Monday, 13 November 2006

Days.daysBetween(today, christmas);

Using Java, how many days are there between now and Christmas? Its actually quite a tricky calculation to get reliably right (Did you forget to handle daylight savings?).

Now you no longer need to write it yourself if you use version 1.4 of Joda-Time:

LocalDate today = new LocalDate();
LocalDate christmas = new LocalDate(2006, 12, 25);
Days daysToChristmas = Days.daysBetween(today, christmas);

So what's going on here? Well its pretty readable really, but we are (a) creating two date objects (no time, no timezone) and (b) calculating the days between the dates. The calculation effectively includes the start date and excludes the end date. Issues with daylight savings time are avoided by using the no timezone LocalDate objects. But what if you want to calculate the number of days considering time, lets say 08:00 on christmas morning?

DateTime now = new DateTime();
DateTime christmas = new DateTime(2006, 12, 25, 8, 0, 0, 0);
Days daysToChristmas = Days.daysBetween(today, christmas);

Well, that's pretty similar! Internally, the code will count the number of whole days between the datetimes. Or put another way, how many 24 hours units are there between the two datetimes (except that it handles 23/25 hours DST dates too!). So, 08:01 on christmas eve returns zero days, but 07:59 returns one day.

And what's the other noticeable feature about the code above? Well, the result is being returned as an object, Days, not as an int. This allows your application to store a value in days, and actually know it is days and not some random int.

Up until now in Joda-Time, we have used the Period class for this. But that allowed you flexibility in storing a period such as "3 days, 12 hours and 32 minutes" - fine if you want that flexibility, but not if you don't. Days on the other hand can only store a number of days.

Now, you may be asking what is so special about days? Why can't I calculate the difference between months or hours. Well, of course you can! The new classes are Years, Months, Weeks, Days, Hours, Minutes and Seconds. They all operate in a similar manor, and they all implement the relevant interface, ReadablePeriod so they can interoperate.

Oh, and one last point. the factory method have a naming style that allows them to be statically imported on Java SE 5. Still not sure if I really like static imports, but at least the API supports the coding style!

As always, any feedback on Joda-Time is welcomed, here, mailing list or forum. With your help, the library can improve still further!

Wednesday, 23 August 2006

Which days of the week are the weekend in Egypt?

Do you know? Or more precisely, does your Java application know?

Well, yesterday I released a 0.1 version of a new project Joda-Time-I18N. This provides four lookups at present:

  • Time zone by territory
  • First day of week by territory
  • Business days by territory
  • Weekend days by territory

The data comes from the Unicode CLDR project, so should be pretty accurate (its backed by IBM and Sun).

The code is released now to get some feedback, and to allow early users access. The 0.1 version refers to the chance of the API changing (high), not the quality of the data (which is good). Oh, and the weekend in Egypt?

  Territory t = Territory.forID("EG");
  int weekendStartDay = t.getWeekendStart();
  int weekendEndDay = t.getWeekendEnd();

Anyway, I'd love to here any feedback on the API, data or proposed enhancements.

Wednesday, 2 August 2006

Joda-Time 1.3 released

Well, it took a while, but the next release of Joda-Time is finally here. Version 1.3 includes two main enhancements in addition to the bug fixes:

Three new datetime classes have been added - LocalDate, LocalTime and LocalDateTime. These represent a date, time or datetime without a time zone. As such LocalDate is a direct replacement for YearMonthDay, whilst LocalTime replaces TimeOfDay. Neither of the replaced classes has been deprecated yet however, due to their widespread adoption.

The new Local* classes use a more standard and reliable implementation internally, and fix some weird external semantics of the older classes. For example, it was not possible to query the dayOfWeek on a YearMonthDay (because it only holds year, month and day!). LocalDate uses a different implementation, so that restriction no longer applies.

The second major enhancement is the addition of convenience methods to change each field value - immutable equivalent of set methods. Here is how to set the day to the first day of the month, constrasting before and after:

// previously
firstOfMonth = dt.dayOfMonth().setCopy(1);

// version 1.3
firstOfMonth = dt.withDayOfMonth(1);

Clearly, the new code is more readable and understandable. Note that as Joda-Time objects are immutable, the methods return a new instance with that field value changed. This is emphasised by the use of the verb 'with' rather than 'set'

As always, feedback is welcomed - whether bugs or reviews, good or bad! Only with input from the community can the library improve.

Thursday, 6 July 2006

A better datetime library JSR?

Do you hate the JDK Date and Calendar classes? Would you like to see an alternative in the JDK? Or are you happy with the JDK classes? Maybe you are happy with pulling in a jar file?

I ask because I get asked from time to time whether Joda-Time is going to get a JSR. Each time this comes up I point out that its a lot of work to do in my free time, and there are infrequent enough releases as is!

So, this blog is an open question - is it worth it? Should JDK7 contain a better datetime library? Please add a comment with your views, postive and negative so I can get some idea of peoples thoughts!

Friday, 30 December 2005

Joda-Time subprojects released

I've just finished releasing the Joda-Time hibernate support (0.8) and Joda-Time JSP tags (0.9) subprojects.

Both these projects are still officially pre a 1.0 release, however its good to have them available properly. I had intended to release the jsptags project as 1.0, but a cunning plan ensued which caused me to go to 0.9 instead. Hopefully I can confess what I've been up to soon, its really very useful!

Thursday, 22 December 2005

Joda-Time 1.2 is released

I had hoped it might have been released before Javapolis, but time pressures came into play (no pun intended!) Anyway, Joda-Time 1.2, the replacement for JDK Date and Calendar, is now released!

This release fixes a few bugs and upgrades to the latest time zone information. It also includes two new calendar systems, Ethiopic and Islamic. I am still looking to expand the range of calendar systems though, there are numerous ones still to add.

Also added were convenience methods on properties to create an interval for a whole month/week etc (toInterval), and to set a date to the last day in a month (withMaximumValue).

The feedback from Joshua Bloch and the rest of the audience at Javapolis was useful, and I expect to enhance and clarify the API over the coming year.

Full details can be found on the website. As always, feedback welcome!

Thursday, 11 August 2005

Joda-Time 1.1 is released

It took a while, but version 1.1 of Joda-Time, the replacement for JDK Date and Calendar, has been released!

This release does fix a few bugs, however these were mostly relatively minor. It does however include a number of useful new methods and usability enhancements. For example:

  • a new Partial class, allowing any group of datetime fields to be defined. A typical use might be to create a YearMonth object for a credit card
  • new convenience methods for adding periods, such as plusDays(n) or minusHours(n)
  • YearMonthDay and TimeOfDay are now comparable
  • new methods to create a Period from two YearMonthDay or two TimeOfDay objects
  • new methods on Interval - gap, abuts and overlap
  • better handling of two digit years in formatting/parsing
  • added ISO formats for ordinal (dayOfYear) dates

And stay tuned for announcements about Hibernate and JSP integration!

Full details can be found on the website.

Oh, and if anyone wants to help develop another calendar systems, such as Hebrew, Islamic, Chinese, etc. then please contact me!!!

Tuesday, 22 February 2005

Joda-Time 1.0 released

Yes, its finally here! Joda-Time, the replacement for JDK Date and Calendar (and much more) has reached 1.0!

Full details can be found on the website. However, let me draw out a few key features:

- Easy to Use - Calendar makes accessing 'normal' dates difficult, due to the lack of simple methods. Joda-Time has straightforward field accessors. And the index of January is 1!

- Extensible - Joda-Time supports multiple calendar systems via a plugin mechanism, which is much more extensible than the subclasses of Calendar. Currently supported calendars are ISO8601, GregorianJulian, Buddhist (Thai) and Coptic.

- Comprehensive - Joda-Time includes classes for datetimes, dates without times, times without dates, intervals and time periods.

- Advanced formatting - An advanced and extensible formatting mechanism is included, allowing input and output to string in a thread-safe manner.

- Well documented. There is documentation in the form of a quick and full user guide, plus reference pages, FAQs and javadoc.

- Tested. There is good test coverage, see the website, providing an assurance of quality.

- Built in security. Advanced operations that could prove a security risk (like changing the current time) are protected by standard JDK security.

And if you learn best by an example:

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = Period.days(2);
  return datetimeRented.plus(rentalPeriod).isBeforeNow()
}
public boolean isJoinedInLastThreeMonths(DateTime datetimeJoined) {
  Interval last3Months = new Interval(Period.months(3), new DateTime());
  return last3Months.contains(datetimeJoined);
}
public boolean isBirthdayInLeapYear(YearMonthDay dateOfBirth) {
  return dateOfBirth.year().isLeap();
}

So, now its released, what next? Well I hope that some of you reading this will want to help add some other calendar systems, such as Hebrew, Islamic, Chinese, etc. Any takers?

Wednesday, 16 February 2005

Joda-Time 0.99 done, 1.0 on its way...

Yes, after lots of late nights, version 0.99 of Joda-Time (the replacement for JDK Date and Calendar, and much much more) is out in the wild.

The plan is to get a few days feedback on 0.99, remove the deprecated methods, then release as 1.0 next week (and definitely before the end of February).

By the way, if you used version 0.98, you'll need to read the release notes, as there were a few last minute changes between 0.98 and 0.99. But I'm determined to let nothing stop 1.0 ;-)

Oh, and if you want to help out by developing another calendar system, Hebrew, Islamic, Chinese, Thai, Japanese,... just drop me a line !

Saturday, 6 November 2004

Joda-Time 0.98 released

Well, it took long enough, but finally its here. The new release of Joda-Time , the cleanroom replacement to JDK Date and Calendar. So whats in it?

  • DateTime - a millisecond based datetime + timezone
  • DateMidnight - a millisecond based date + timezone
  • YearMonthDay - a field based date without zone
  • TimeOfDay - a field based time without zone
  • Duration - a millisecond based length of time (23456 ms)
  • Period - a field based length of time (5 months, 2 days and 4 hours)
  • Interval - a time interval between two exact points in time

Those who've played with Joda-Time before will spot that some classes have changed. TimeOnly became TimeOfDay, DateOnly became DateMidnight or YearMonthDay depending on your requirements. This was all necessary to solve issues that only became apparant during testing. This is one project where test driven development might actually have produced a better design earlier, not just bug free code. Ah well, isn't hindsight great...