Time

178 views
Skip to first unread message

Rich Oliver

unread,
Mar 6, 2013, 10:04:09 AM3/6/13
to scala-l...@googlegroups.com
There doesn't seem to be any time support in Scala. As for Java: well the less said the better. Anyway i suggest two major classes can cover most of our time needs:

object TimeSpan
{
   def apply(ticsInMilliSeconds: Long): TimeSpan = TimeSpan(ticsInMilliSeconds)
}

class TimeSpan(val tics: Long) extends AnyVal
{
   def +(operand: TimeSpan): TimeSpan = TimeSpan(tics + operand.tics)
   def -(operand: TimeSpan): TimeSpan = TimeSpan(tics - operand.tics)
   def *(operand: Long): TimeSpan = TimeSpan(tics * operand)
   def *(operand: Double): TimeSpan = TimeSpan((tics * operand).toLong)
   def /(operand: Long): TimeSpan = TimeSpan(tics / operand)
   def /(operand: Double): TimeSpan = TimeSpan((tics / operand).toLong)
   def toSecsonds: Long = tics / 1000
   def toMinutes: Long = tics / 60000
   def toHours: Long = tics / 3600000
}

object TimeDate
{
   def apply(ticsInMilliSecondsRelativeTo1970: Long): TimeDate = new TimeDate(ticsInMilliSecondsRelativeTo1970)
   def apply(year: Int, month: Int, day: Int) = new TimeDate(new JGreg(year, month, day).getTimeInMillis())  
}

class TimeDate(val tics: Long) extends AnyVal
{  
   def +(operand: TimeSpan): TimeDate = TimeDate(tics + operand.tics)
   def -(operand: TimeSpan): TimeDate = TimeDate(tics - operand.tics)
   def --(operand: TimeDate): TimeSpan = TimeSpan(tics - operand.tics)  
}

That's just a starter, lots of methods required to input and output local times, different calenders etc. Conversions to Java classes can be provided as methods. The key point is that one very cheap class DateTime can implement the log on time of you in London, the log on time of your colleague in New York, the Battle of Hastings and the extinction of the Dinosaurs. I would then suggest helper objects such as:
.
object Hour
{
   def apply: TimeSpan = new TimeSpan(3600000)
   def apply(numberOfWholeHours: Long): TimeSpan = new TimeSpan(numberOfWholeHours * 3600000)
   def inDou(value: Double): TimeSpan = new TimeSpan((value * 3600000).toLong)
}
object Minute
{
   def apply: TimeSpan = new TimeSpan(60000)
   def apply(numberOfWholeMinutes: Long): TimeSpan = new TimeSpan(numberOfWholeMinutes * 60000)
   def inDou(value: Double): TimeSpan = new TimeSpan((value * 60000).toLong)
}
object Second
{
   def apply: TimeSpan = new TimeSpan(1000)
   def apply(numberOfWholeSeconds: Long): TimeSpan = new TimeSpan(numberOfWholeSeconds * 1000)
   def inDou(value: Double): TimeSpan = new TimeSpan((value * 1000).toLong)
}

Some additional classes might also be useful such as:

object WholeHours
{
    def apply(numberOfWholeHours: Int): WholeHours = new WholeHours(numberOfWholeHours)
}
class WholeHours(val value: Int) extends AnyVal
{
   def +(operand: WholeHours): WholeHours = new WholeHours(value + operand.value)
   def toTimeSpan: TimeSpan = new TimeSpan(value * 3600000)
}

Tom Switzer

unread,
Mar 6, 2013, 10:09:40 AM3/6/13
to scala-l...@googlegroups.com
Would Joda Time w/ some slight enrichment solve your needs? It is quite a nice (Java) library.


--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

ARKBAN

unread,
Mar 6, 2013, 10:11:30 AM3/6/13
to scala-l...@googlegroups.com
+1

A library that Scala-izes JodaTime (or some other library) would be a better approach.

ARKBAN

Joshua Serrin

unread,
Mar 6, 2013, 10:12:58 AM3/6/13
to scala-l...@googlegroups.com

Adam Shannon

unread,
Mar 6, 2013, 10:12:55 AM3/6/13
to scala-l...@googlegroups.com
Have you guys seen this?

https://github.com/jorgeortiz85/scala-time
Adam Shannon
Developer
University of Northern Iowa
Junior -- Computer Science & Mathematics
http://ashannon.us

Simon Ochsenreither

unread,
Mar 6, 2013, 10:17:01 AM3/6/13
to scala-l...@googlegroups.com
Use https://github.com/ThreeTen. Despite the fact that the author hates Scala, the library/API is as Scala-like as it can get considering it is implemented in Java.

Rich Oliver

unread,
Mar 6, 2013, 10:42:26 AM3/6/13
to scala-l...@googlegroups.com
Why wrap Joda? By that logic why have scala collections when we could wrap the Java ones or Google's. All the time classes are are Doubles. With value classes there's no wrapper required at all. I accidentally left a second method in the TimeDate object from my own code. I meant to keep the code clean. i'm currently using Java's Gregorian/calender class to input and output. Its very easy to add methods to convert to and from Joda or any other Time class. I'm proposing that these Time classes should be in the global name space. One standard measure of time that everyone everywhere in the world using Scala can use. Its naturally convertible to the standard time measures in Java and C. Its so lightweight that not only could you time stamp jars and applicaton versions, you could even time stamp classes. We have standard classes for integers, for floating point numbers and for strings. We wouldn't dream of wrapping up a Java String class. Why should we wrap up a Time class. With multi-cores and distributed computing a standard encoding of time is essential. Its an incredibly basic and common form of data.


Paul Phillips

unread,
Mar 6, 2013, 10:54:05 AM3/6/13
to scala-l...@googlegroups.com

On Wed, Mar 6, 2013 at 7:42 AM, Rich Oliver <rzi...@gmail.com> wrote:
We wouldn't dream of wrapping up a Java String class.

Well...

Tom Switzer

unread,
Mar 6, 2013, 11:03:28 AM3/6/13
to scala-l...@googlegroups.com
No, the logic doesn't follow to your conclusion. My logic is simple; use the best tool available for the job. Scala collections offer far more than Java's do. If Scala's collections were inferior to Java's, I'd certainly lobby for their removal. However, Joda time is a fantastic date library. Why would you not use it? I use Java libraries all the time.

On Wed, Mar 6, 2013 at 8:42 AM, Rich Oliver <rzi...@gmail.com> wrote:
Why wrap Joda? By that logic why have scala collections when we could wrap the Java ones or Google's. All the time classes are are Doubles. With value classes there's no wrapper required at all. I accidentally left a second method in the TimeDate object from my own code. I meant to keep the code clean. i'm currently using Java's Gregorian/calender class to input and output. Its very easy to add methods to convert to and from Joda or any other Time class. I'm proposing that these Time classes should be in the global name space. One standard measure of time that everyone everywhere in the world using Scala can use. Its naturally convertible to the standard time measures in Java and C. Its so lightweight that not only could you time stamp jars and applicaton versions, you could even time stamp classes. We have standard classes for integers, for floating point numbers and for strings. We wouldn't dream of wrapping up a Java String class. Why should we wrap up a Time class. With multi-cores and distributed computing a standard encoding of time is essential. Its an incredibly basic and common form of data.

Paul Hudson

unread,
Mar 6, 2013, 11:07:56 AM3/6/13
to scala-l...@googlegroups.com
>Why wrap Joda?

Because..

That's just a starter, lots of methods required to input and output local times, different calenders etc

... getting this right is a ton of work. 


On 6 March 2013 15:42, Rich Oliver <rzi...@gmail.com> wrote:
Why wrap Joda? By that logic why have scala collections when we could wrap the Java ones or Google's. All the time classes are are Doubles. With value classes there's no wrapper required at all. I accidentally left a second method in the TimeDate object from my own code. I meant to keep the code clean. i'm currently using Java's Gregorian/calender class to input and output. Its very easy to add methods to convert to and from Joda or any other Time class. I'm proposing that these Time classes should be in the global name space. One standard measure of time that everyone everywhere in the world using Scala can use. Its naturally convertible to the standard time measures in Java and C. Its so lightweight that not only could you time stamp jars and applicaton versions, you could even time stamp classes. We have standard classes for integers, for floating point numbers and for strings. We wouldn't dream of wrapping up a Java String class. Why should we wrap up a Time class. With multi-cores and distributed computing a standard encoding of time is essential. Its an incredibly basic and common form of data.

Simon Ochsenreither

unread,
Mar 6, 2013, 11:20:10 AM3/6/13
to scala-l...@googlegroups.com


However, Joda time is a fantastic date library. Why would you not use it? I use Java libraries all the time.

Tom Switzer

unread,
Mar 6, 2013, 11:36:47 AM3/6/13
to scala-l...@googlegroups.com
Cool! Looks like this will be part of Java 8.

On Wed, Mar 6, 2013 at 9:20 AM, Simon Ochsenreither <simon.och...@gmail.com> wrote:


However, Joda time is a fantastic date library. Why would you not use it? I use Java libraries all the time.

--

Oliver Ruebenacker

unread,
Mar 6, 2013, 11:38:20 AM3/6/13
to scala-l...@googlegroups.com
Hello,

On Wed, Mar 6, 2013 at 10:42 AM, Rich Oliver <rzi...@gmail.com> wrote:
> why have scala collections

http://mkaz.com/solog/10-scala-one-liners-to-impress-your-friends

Take care
Oliver

--
IT Project Lead at PanGenX (http://www.pangenx.com)
The purpose is always improvement

Rich Oliver

unread,
Mar 6, 2013, 11:47:05 AM3/6/13
to scala-l...@googlegroups.com
From what I can make out the computing calender is highly standardised. Its measured relative to Midnight in Greenwich on the first of Jan 1970, Whether this was chosen as a tribute to Rolf Harris or as an anti war gesture, I don't know. His hit single "Two Little Boys" was number one in the British charts at the Time. However whatever the reason that's the standard. Mostly its measured in miliseconds, which is precise enough for most purposes, although obviously some modern applications will require greater precison. To store and manipulate these TimeDates is incredibly easy and incredibly cheap in terms of storage and processing.

I would also suggest that its fairly obvious how to do it. C# has its DateTime and TimeSpan classes. I'm not sure if their DateTimeOffset class has really helped but you don;t have to use it if you don;t want to. How Java managed to make a pig's ear of something so straightforward is beyond me. Time is very easy for computers to manipulate. Humans complicate things wanting it presented in various time zones, daylight savings, calenders, languages and fonts. However that doesn't matter because humans are slow. So simple, fast, efficient, clean, rationale Computing Time can easily be translated into what ever bizarre form the human wants when required.

Wrapping Swing or JavaFx classes makes sense. There's' a huge amount of functionality in those APIs which would take a lot of person hours to create from scratch. Wrapping Time does not make sense. There's nothing to it. Its just some basic arithmetic operations and a few (non-performance critical) pretty printer functions.

Simon Ochsenreither

unread,
Mar 6, 2013, 11:58:44 AM3/6/13
to scala-l...@googlegroups.com

From what I can make out the computing calender is highly standardised. Its measured relative to Midnight in Greenwich on the first of Jan 1970, Whether this was chosen as a tribute to Rolf Harris or as an anti war gesture, I don't know. His hit single "Two Little Boys" was number one in the British charts at the Time. However whatever the reason that's the standard. Mostly its measured in miliseconds, which is precise enough for most purposes, although obviously some modern applications will require greater precison. To store and manipulate these TimeDates is incredibly easy and incredibly cheap in terms of storage and processing.

I would also suggest that its fairly obvious how to do it. C# has its DateTime and TimeSpan classes. I'm not sure if their DateTimeOffset class has really helped but you don;t have to use it if you don;t want to. How Java managed to make a pig's ear of something so straightforward is beyond me. Time is very easy for computers to manipulate. Humans complicate things wanting it presented in various time zones, daylight savings, calenders, languages and fonts. However that doesn't matter because humans are slow. So simple, fast, efficient, clean, rationale Computing Time can easily be translated into what ever bizarre form the human wants when required.

Wrapping Swing or JavaFx classes makes sense. There's' a huge amount of functionality in those APIs which would take a lot of person hours to create from scratch. Wrapping Time does not make sense. There's nothing to it. Its just some basic arithmetic operations and a few (non-performance critical) pretty printer functions.

Sorry, but no. A straight no to all of your assumptions. Time is incredibly hard. There are even multiple competing standards on how to count the milliseconds from 1970, all of which are used for certain purposes. Leap seconds are only standardized since 1972, so we have two full years where we don't have any agreement on how much time elapsed exactly between 1970 and 1972. And don't get me started on timezones and calenders: http://www.amazon.com/dp/0521702380/

There is a reason why almost no system on this planet gets time even remotely right.

Nils Kilden-Pedersen

unread,
Mar 6, 2013, 12:02:45 PM3/6/13
to scala-l...@googlegroups.com

Bingo. Time/calendar is an example of the more you know, the less you know.
 

ARKBAN

unread,
Mar 6, 2013, 12:47:33 PM3/6/13
to scala-l...@googlegroups.com
While .NET (C#) has its own DateTime and TimeSpan classes, they are not near the level of Joda Time, hence Noda Time.

.NET's core time classes work well because they are very dumb and do not try to be all-singing all-dancing time framework.

ARKBAN

Rüdiger Klaehn

unread,
Mar 6, 2013, 1:47:30 PM3/6/13
to scala-l...@googlegroups.com
Unfortunately, not dumb enough. The upper two bits of a DateTime encode whether the time is local, utc or unspecified. Which causes various problems. 

If you want something fast and don't care about locales, calendars, leap seconds etc. just wrap a Long in a value class. We use microseconds since the unix epoch, which gives sufficient precision for most cases. If you do care, use something like JodaTime. 

Mark Derricutt

unread,
Mar 6, 2013, 8:00:30 PM3/6/13
to scala-l...@googlegroups.com
Simon Ochsenreither wrote:
- hide quoted text -- show quoted text -
However, Joda time is a fantastic date library. Why would you not use it? I use Java libraries all the time.
--

ThreeTen is also the backport of JSR-310 available in Maven Central and works with Java 7:

  https://github.com/ThreeTen/threeten/

If anything, it would be good to make a Scala wrapper around ThreeTen/JSR-310 adding any and all niceties to make it more scala friendly.


Mark Derricutt

unread,
Mar 6, 2013, 8:04:24 PM3/6/13
to scala-l...@googlegroups.com
Mark Derricutt wrote:
> ThreeTen is also the backport of JSR-310 available in Maven Central
> and works with Java 7:
>
> https://github.com/ThreeTen/threeten/
Correction - the backport repo is:

https://github.com/ThreeTen/threetenbp

Rich Oliver

unread,
Mar 7, 2013, 8:12:58 AM3/7/13
to scala-l...@googlegroups.com
On Thursday, March 7, 2013 1:00:30 AM UTC, Mark Derricutt wrote:
Simon Ochsenreither wrote:
- hide quoted text -- show quoted text -
However, Joda time is a fantastic date library. Why would you not use it? I use Java libraries all the time.
--

ThreeTen is also the backport of JSR-310 available in Maven Central and works with Java 7:
 
If anything, it would be good to make a Scala wrapper around ThreeTen/JSR-310 adding any and all niceties to make it more scala friendly.

The Instant and Period classes should not be wrapped. They should be Long value classes, athough I guess it makes sense to use micro tics in line with JSR 310 rather than milli tics. Manipulating raw time is simple and should be kept simple the same as manipulating raw integers. 3 + 2 = 5 is simple. Inputing 'Bet' and 'Gimel' and then outputting their sum on the screen or on a printer in Japan as 'go' is complicated and we're naturally going  to use Java libraries and other non Scala utilities. Similarly with time.

As for the question of how many leap seconds there were between 1970 and 1972, Its not an issue, I feel strongly about. I'd be quite happy to use what ever calculation Java 8 uses.
 
 

Alec Zorab

unread,
Mar 7, 2013, 8:18:12 AM3/7/13
to scala-l...@googlegroups.com
Okay, and when you do Now + 1.day, what calculation do you expect to happen?
Tip: Your answer is either not-simple or it is wrong.


 

--

Jeff Olson

unread,
Mar 8, 2013, 1:50:16 AM3/8/13
to scala-l...@googlegroups.com
FWIW, I have actually written a scala time library very much along the lines of what Rich is proposing (unfortunately closed source as of this moment). So I'll be so bold as to offer my 2 cents.

Writing a date-time library is not nearly so difficult as many people make it out to be, *provided* (big caveat) one is willing to make some simplifying assumptions. For instance, my library only supports the Gregorian calendar for times in the range of (roughly) 1677-09-21 until 2262-04-11, and it only supports certain well-behaved time zones (most of the ones anyone really cares about). All told, it is about 1200 lines of scala code, nearly half of which are devoted to parsing and formatting. It does 99.9% of what I want a time library to do (and probably 95% of what 90% of people would want a time library to do).

The joda-time library is extremely general and is capable of handling numerous calendar systems in every conceivable time zone. It pays for this generality in complexity, performance, and usability. That said, even the mighty joda-time library makes simplifying assumptions. For example, even it does not account for leap seconds (http://joda-time.sourceforge.net/faq.html#leapseconds). If you ask try to ask joda-time for the number of seconds between the epoch (1970-01-01T00:00:00Z) and 2013-01-01T00:00:00Z it will incorrectly tell you that there were 1356998400 seconds. It actualality there where 1356998425 seconds.

So why did I choose to write my own time library rather than just using (or wrapping joda-time)? A number of reasons:

1. joda-time only supports millisecond resolution; I needed a library with nanosecond resolution
2. joda-time is extremely verbose and cumbersome; I wanted a compact, easy-to-use scala DSL
3. certain operations in joda-time are very, very, sloooow; I needed a high-performance library
4. joda-time is too general for my purposes, it makes everything possible, but easy things are too difficult

That said, everyone's requirements differ, and for most people I think a scala wrapper of joda-time would be more than sufficient.

For anyone interested, my library consists of five basic types: Time, Duration, Date, TimeOfDay, and TimeZone. Time, Duration, and TimeOfDay are all value-classes wrapping a Long or Int. Time is a time-zone agnostic representation of an instant in time (represented as the number of nanoseconds since the epoch). Duration is simply a Long representing a fixed number of nanoseconds. Date is semantically a year-month-day triple and TimeOfDay is a cyclic long with a period of 86400 * 10^9 nanoseconds.

One advantage of writing a time library in scala, besides having a nice compact DSL, is the ability to write functions that take an implicit TimeZone whenever necessary. For instance, my Time class (which itself is time-zone agnostic) has functions like:

def date(implicit tz: TimeZone): Date
def tod(implicit tz: TimeZone): TimeOfDay
def midnight(implicit tz: TimeZone): Time

and my Date class has a function

def at(tod: TimeOfDay)(implicit tz: TimeZone): Time

The hardest part about writing this library (apart from the parsing and formatting code) was getting the Daylight Savings Time (DST) transitions correct. DST transitions are extremely complex (being subject to the whims of local government), but, for the most part, this complexity is handled by the standard tz database, which is freely available and easy to use. Even joda-time uses this database to handle DST transitions.

Yes, there are some decisions to make about how to handle DST transitions, but these are not really all that difficult. By way of example, let me answers Alec's question about the meaning of now + 1.day. In my library, 1.day is a fixed duration which is always 24 hours. So now + 1.day is the same as now + 24.hours. Because of DST transitions it is not always true that now.tod == (now + 1.day).tod. If you wanted the next day at the same time of day you could write instead

(now.date + 1).at(now.tod)

with some implicit TimeZone in scope. But of course the difference between those two times may not be exactly 24 hours.

Okay, that was more like 20 cents. Sorry for the long post.
Cheers, Jeff

Francois

unread,
Mar 8, 2013, 9:12:45 AM3/8/13
to scala-l...@googlegroups.com, Jeff Olson
Le 08/03/2013 07:50, Jeff Olson a écrit :
FWIW, I have actually written a scala time library very much along the lines of what Rich is proposing (unfortunately closed source as of this moment). So I'll be so bold as to offer my 2 cents.

Writing a date-time library is not nearly so difficult as many people make it out to be, *provided* (big caveat) one is willing to make some simplifying assumptions.

And provided a hight level of knowledge on the topic (and obviously, you have much more knowledge on it than the lambda guy saying "why using that big time library, I only need...")

[...]

Okay, that was more like 20 cents. Sorry for the long post.

That was *really* intersting, thanks ! Is there a possibilty that you library will be open-sourced at some time ? I think it could be great even if it's only to see how a rich and performant domain can be biuld around value classes and implicit parameters.

Cheers,
-- 
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com

Lanny Ripple

unread,
Mar 8, 2013, 11:17:06 AM3/8/13
to scala-l...@googlegroups.com
It was chosen because Unix had just been released and the start of the closest year seemed as good as any.  Folks then decided that maybe the closest decade would be a bit more consistent.

  http://en.wikipedia.org/wiki/Unix_time#History

And the fact that you even struck upon the Unix Epoch was because you happen to be using Scala which runs on the JVM which was created at Sun which was a Unix shop.

Rich Oliver

unread,
Mar 8, 2013, 11:50:50 AM3/8/13
to scala-l...@googlegroups.com
On Friday, March 8, 2013 4:17:06 PM UTC, Lanny Ripple wrote:
It was chosen because Unix had just been released and the start of the closest year seemed as good as any.  Folks then decided that maybe the closest decade would be a bit more consistent.

Ah so the epoch of "worse is better" : The Kali Yuga of computing.
Reply all
Reply to author
Forward
0 new messages