TimeDuration.st
author Claus Gittinger <cg@exept.de>
Tue, 26 Feb 2008 11:29:14 +0100
changeset 1930 935b2870be2e
parent 1905 ec30ff95406a
child 1989 fbaeabdda6bd
permissions -rw-r--r--
arrow points reusable (class protocol)

"
 COPYRIGHT (c) 1989 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libbasic2' }"

Time subclass:#TimeDuration
	instanceVariableNames:''
	classVariableNames:'TimeDurationZero'
	poolDictionaries:''
	category:'Magnitude-Time'
!

!TimeDuration class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1989 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
"
! !

!TimeDuration class methodsFor:'instance creation'!

days:d 
    "return a new TimeDuration representing a duration of d days."

    ^ self hours:(d*24) minutes:0

    "
     TimeDuration days:1  
    "
!

fromMilliseconds:millisecondsInterval
    "redefined to disable wrapping at 24hours."

    ^ self new setMilliseconds:millisecondsInterval

    "
     TimeDuration fromMilliseconds:500  
    "

    "Created: / 18-07-2007 / 13:56:25 / cg"
!

fromMinutes:minutesInterval
    ^ self new setSeconds:(minutesInterval * 60)

    "
     TimeDuration fromMinutes:120  
    "
!

fromSeconds:secondsInterval
    "redefined to disable wrapping at 24hours."

    ^ self new setSeconds:secondsInterval

    "
     TimeDuration fromSeconds:3600  
    "
!

hours:h
    "return a new TimeDuration representing a duration of h hours.
     See also Time now / Date today / Timestamp now."

    ^ self basicNew setHours:h minutes:0 seconds:0 milliseconds:0

    "
     TimeDuration hours:2 
     TimeDuration hours:100  
    "

    "Created: / 14-07-2007 / 18:15:51 / cg"
!

hours:h minutes:m
    "return a new TimeDuration representing a duration of h hours and m minutes.
     See also Time now / Date today / Timestamp now."

    ^ self basicNew setHours:h minutes:m seconds:0 milliseconds:0

    "
     TimeDuration hours:2 minutes:33 
     TimeDuration hours:100 minutes:33  
    "
!

hours:h minutes:m seconds:s millis:millis
    "return a new TimeDuration representing a duration of h hours, m minutes, s seconds and millis milliseconds.
     See also Time now / Date today / Timestamp now."

    self obsoleteMethodWarning:'use hours:minutes:seconds:milliseconds:'.
    ^ self hours:h minutes:m seconds:s milliseconds:millis

    "
     TimeDuration hours:2 minutes:33 seconds:0 milliseconds:123  
     TimeDuration hours:100 minutes:33 seconds:0 milliseconds:123  
    "
!

hours:h minutes:m seconds:s milliseconds:millis
    "return a new TimeDuration representing a duration of h hours, m minutes, s seconds and millis milliseconds.
     See also Time now / Date today / Timestamp now."

    ^ self basicNew 
        setHours:h minutes:m seconds:s milliseconds:millis

    "
     TimeDuration hours:2 minutes:33 seconds:0 milliseconds:123  
     TimeDuration hours:100 minutes:33 seconds:0 milliseconds:123  
    "
!

minutes:m
    "return a new TimeDuration representing a duration of m minutes.
     See also Time now / Date today / Timestamp now."

    ^ self basicNew setHours:0 minutes:m seconds:0 milliseconds:0

    "
     TimeDuration minutes:2 
    "

    "Created: / 06-08-2007 / 15:32:42 / cg"
!

readFrom:aStringOrStream onError:exceptionBlock
    "return a new TimeDuration, reading a printed representation from aStream.
     The format is [n 'd'] [n 'h'] [n 'm'] [n 's']"

    ^ [
        |seconds millis str val fraction uIdx unit unitChar1 unitChar2|

        str := aStringOrStream readStream.
        seconds := 0.
        millis := 0.
        [
            val := Integer readFrom:str onError:nil.
            val isNil ifTrue:[^ exceptionBlock value].
            str peek == $. ifTrue:[
                str next.
                fraction := Number readMantissaFrom:str radix:10.
                val := val + fraction.
            ].
            str skipSeparators.
            str atEnd ifTrue:[
                "/ no unit given - assume seconds
                ^ self fromSeconds:val.
                "/ ^ exceptionBlock value
            ].

            unitChar1 := str next.
            uIdx := #($d $h $m $s) indexOf:unitChar1.
            uIdx == 0 ifTrue:[^ exceptionBlock value].
            (unitChar1 == $m and:[str peek == $s]) ifTrue:[
                str next.
                millis := millis + val.
            ] ifFalse:[
                unit := #(86400 "24*60*60"
                          3600
                          60
                          1 ) at:uIdx.
                seconds := seconds + (unit * val).
            ].
            str skipSeparators.
            str atEnd
        ] whileFalse.
        self fromMilliseconds:(seconds*1000+millis) rounded asInteger.
    ] on:Error do:exceptionBlock.

    "
     TimeDuration readFrom:'1h'      
     TimeDuration readFrom:'1h 35m'     
     TimeDuration readFrom:'25h'     
     TimeDuration readFrom:'3d'     
     TimeDuration readFrom:'120s'     
     TimeDuration readFrom:'1500ms    
     TimeDuration readFrom:'3ms'     
    "

    "Modified: / 08-10-2007 / 16:41:48 / cg"
!

seconds:s
    "return a new TimeDuration representing a duration of s seconds.
     See also Time now / Date today / Timestamp now."

    ^ self basicNew setHours:0 minutes:0 seconds:s milliseconds:0

    "
     TimeDuration seconds:2 
    "

    "Created: / 06-08-2007 / 15:32:21 / cg"
! !

!TimeDuration class methodsFor:'class initialization'!

initialize
    TimeDurationZero isNil ifTrue:[
        TimeDurationZero := self seconds:0.
    ]
! !

!TimeDuration class methodsFor:'constants'!

zero
    "return the neutral element for addition (0s)"

    ^ TimeDurationZero

    "Modified: 18.7.1996 / 12:26:12 / cg"
! !

!TimeDuration class methodsFor:'format strings'!

formatString12us
    "return the format string used to format US times (and other areas)"

    ^ '%h:%m:%s.%i'
!

formatString24
    "return the format string used to format european times (and other areas)"

    ^ '%h:%m:%s.%i'
! !

!TimeDuration methodsFor:'accessing'!

days
    ^ timeEncoding // 1000 // 3600 // 24
!

milliseconds
    ^ timeEncoding \\ 1000
! !

!TimeDuration methodsFor:'arithmetic'!

* aNumber
    "return a new timeDuration"

    ^ self species basicNew 
        setMilliseconds:(self getMilliseconds * aNumber) asInteger

    "
     (TimeDuration fromString:'10s') * 5
    "
!

+ aTimeDurationOrNumberOfSeconds
    "return a new timeDuration"

    aTimeDurationOrNumberOfSeconds isNumber ifTrue:[
        ^ self species basicNew 
            setMilliseconds:(self getMilliseconds + (aTimeDurationOrNumberOfSeconds * 1000) asInteger)
    ].
    ^ self species basicNew
        setMilliseconds:(self getMilliseconds + aTimeDurationOrNumberOfSeconds getMilliseconds)

    "Created: / 04-10-2007 / 14:12:40 / cg"
!

- aTimeDurationOrNumberOfSeconds
    "return a new timeDuration"

    aTimeDurationOrNumberOfSeconds isNumber ifTrue:[
        ^ self species basicNew 
            setMilliseconds:(self getMilliseconds - (aTimeDurationOrNumberOfSeconds * 1000) asInteger)
    ].
    ^ self species basicNew
        setMilliseconds:(self getMilliseconds - aTimeDurationOrNumberOfSeconds getMilliseconds)

    "Created: / 04-10-2007 / 14:12:29 / cg"
!

/ aTimeDurationOrNumberOfSeconds
    "return a new timeDuration"

    aTimeDurationOrNumberOfSeconds isNumber ifTrue:[
        ^ self species basicNew 
            setMilliseconds:(self getMilliseconds / aTimeDurationOrNumberOfSeconds) asInteger
    ].
    ^ (self getMilliseconds / aTimeDurationOrNumberOfSeconds getMilliseconds)

    "
     (TimeDuration fromString:'10s') / (TimeDuration fromString:'5s')
     (TimeDuration fromString:'10s') / 5
    "
!

productFromFraction:aNumber
    "return a new timeDuration"

    ^ self productFromNumber:aNumber

    "
     (TimeDuration fromString:'10s') * 5
    "
!

productFromNumber:aNumber
    "return a new timeDuration"

    ^ self species basicNew 
        setMilliseconds:(self getMilliseconds * aNumber) asInteger

    "
     (TimeDuration fromString:'10s') * 5
    "
! !

!TimeDuration methodsFor:'converting'!

asTime
    "return a Time object from the receiver - thats the receiver."

    ^ Time hours:(self hours) minutes:(self minutes) seconds:(self seconds)
! !

!TimeDuration methodsFor:'double dispatching'!

sumFromTimestamp:aTimestamp
    ^ aTimestamp addMilliseconds:(self getMilliseconds)
! !

!TimeDuration methodsFor:'printing'!

addPrintBindingsTo:aDictionary language:languageOrNil
    "private print support: add bindings for printing to aDictionary.
     languageOrNil can only be #en or nil for the current language."

    |hoursInDay s|

    super addPrintBindingsTo:aDictionary language:languageOrNil.
    aDictionary at:$d put:self days.

    hoursInDay := self hours \\ 24.
    aDictionary at:#Hd put:(s := hoursInDay printString).
    aDictionary at:#hd put:(s leftPaddedTo:2 with:$0).
!

formatForPrinting
    "Return a format which is suitable for a human - not meant to be read back."

    ^ self formatForPrinting:false
!

formatForPrinting:shortFlag
    "Return a format which is suitable for a human - not meant to be read back.
     If shortFlag is true, some millisecond-info is ommitted for longer times."

    |fmt hours mins secs overAllSeconds millis|

    hours := self hours.
    mins := self minutes.
    secs := self seconds.
    millis := self milliseconds.

    hours >= 24 ifTrue:[
        fmt := '%dd %(Hd)h %Mm'.
        secs = 0 ifTrue:[
            fmt := '%dd %(Hd)h %Mm'.
            mins = 0 ifTrue:[
                fmt := '%dd %(Hd)h'.
                (hours \\ 24) = 0 ifTrue:[
                    fmt := '%dd'.
                ].
            ].
        ].
    ] ifFalse:[
        hours > 0 ifTrue:[
            fmt := '%Hh %Mm'.
            secs = 0 ifTrue:[
                fmt := '%Hh %Mm'.
                mins = 0 ifTrue:[
                    fmt := '%Hh'.
                ].
            ].
        ] ifFalse:[
            mins > 0 ifTrue:[
                fmt := '%Mm'.
                secs = 0 ifTrue:[
                    fmt := '%Mm'
                ].
            ] ifFalse:[
                fmt := ''
            ].
        ].
    ].
    ((secs ~= 0) or:[millis ~= 0])ifTrue:[
        fmt size ~~ 0 ifTrue:[
            fmt := fmt , ' '
        ].
        (millis = 0) ifTrue:[
            fmt := fmt , '%Ss'
        ] ifFalse:[
            secs = 0 ifTrue:[
                fmt := fmt , '%Ims'
            ] ifFalse:[
                shortFlag ifTrue:[
                    overAllSeconds := self asSeconds.
                    overAllSeconds > 2 ifTrue:[
                        overAllSeconds > 10 ifTrue:[
                            overAllSeconds > 300 ifTrue:[
                                fmt := fmt , '%Ss'
                            ] ifFalse:[
                                fmt := fmt , '%S.%(milli1)s'
                            ]
                        ] ifFalse:[
                            fmt := fmt , '%S.%(milli2)s'
                        ]
                    ] ifFalse:[
                        fmt := fmt , '%S.%is'
                    ]
                ] ifFalse:[
                    fmt := fmt , '%S.%is'
                ]
            ]
        ].
    ] ifFalse:[
        fmt isEmpty ifTrue:[
            fmt := '%Ss'
        ].
    ].

    ^ fmt.

    "
     TimeDuration hours:0 minutes:0 seconds:0 millis:12       

     TimeDuration hours:0 minutes:0 seconds:0 millis:123       
     TimeDuration hours:0 minutes:0 seconds:10 millis:123       
     TimeDuration hours:0 minutes:33 seconds:0 millis:123       
     TimeDuration hours:2 minutes:0 seconds:0 millis:123       
     TimeDuration hours:2 minutes:33 seconds:0 millis:123       
     TimeDuration hours:100 minutes:33 seconds:0 millis:123    
     TimeDuration hours:10000 minutes:33 seconds:0 millis:123    
     TimeDuration hours:1000000 minutes:33 seconds:0 millis:123    

     TimeDuration hours:2 minutes:33 seconds:0 millis:0         
     TimeDuration hours:2 minutes:0 seconds:0 millis:0          
     TimeDuration hours:24 minutes:0 seconds:0 millis:0          

     (TimeDuration hours:0 minutes:0 seconds:0 millis:123) printStringFormat:'%h:%m:%s'       
     (TimeDuration hours:0 minutes:0 seconds:10 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:0 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:2 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:100 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
     (TimeDuration hours:10000 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
     (TimeDuration hours:1000000 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
    "

    "Modified: / 18-07-2007 / 14:06:17 / cg"
!

printOn:aStream
    "append a user printed representation of the receiver to aStream.
     The format is suitable for a human - not meant to be read back."

    ^ self
        printOn:aStream 
        format:(self formatForPrinting).

    "
     TimeDuration hours:0 minutes:0 seconds:0 millis:12       

     TimeDuration hours:0 minutes:0 seconds:0 millis:123       
     TimeDuration hours:0 minutes:0 seconds:10 millis:123       
     TimeDuration hours:0 minutes:33 seconds:0 millis:123       
     TimeDuration hours:2 minutes:0 seconds:0 millis:123       
     TimeDuration hours:2 minutes:33 seconds:0 millis:123       
     TimeDuration hours:100 minutes:33 seconds:0 millis:123    
     TimeDuration hours:10000 minutes:33 seconds:0 millis:123    
     TimeDuration hours:1000000 minutes:33 seconds:0 millis:123    

     TimeDuration hours:2 minutes:33 seconds:0 millis:0         
     TimeDuration hours:2 minutes:0 seconds:0 millis:0          
     TimeDuration hours:24 minutes:0 seconds:0 millis:0          

     (TimeDuration hours:0 minutes:0 seconds:0 millis:123) printStringFormat:'%h:%m:%s'       
     (TimeDuration hours:0 minutes:0 seconds:10 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:0 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:2 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'         
     (TimeDuration hours:100 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
     (TimeDuration hours:10000 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
     (TimeDuration hours:1000000 minutes:33 seconds:0 millis:123) printStringFormat:'%h:%m:%s'      
    "

    "Modified: / 18-07-2007 / 14:06:17 / cg"
! !

!TimeDuration methodsFor:'private'!

getMilliseconds
    "return the number of milliseconds"

    ^ timeEncoding

    "Modified: / 18-07-2007 / 13:44:33 / cg"
!

getSeconds
    "return the number of seconds"

    ^ timeEncoding // 1000

    "Modified: / 18-07-2007 / 13:44:37 / cg"
!

setHours:h minutes:m seconds:s millis:millis
    "set my time given individual values"

    self obsoleteMethodWarning:'use setHours:minutes:seconds:milliseconds:'.
    self setHours:h minutes:m seconds:s milliseconds:millis.
!

setHours:h minutes:m seconds:s milliseconds:millis
    "set my time given individual values"

    self setMilliseconds:((h * 60 * 60 ) + (m * 60) + s) * 1000 + millis.
!

setMilliseconds:millis
    "set my duration given milliseconds.
     Notice that (in contrast to Time), there is no modulu operation here.
     Duration can be longer than a day"

    timeEncoding := millis

    "Modified: / 18-07-2007 / 13:44:16 / cg"
!

setSeconds:secs
    "set my timeduration given seconds.
     Notice that (in contrast to Time), there is no modulu operation here.
     Duration can be longer than a day"

    self setMilliseconds:(secs * 1000).

    "Modified: / 18-07-2007 / 13:44:24 / cg"
! !

!TimeDuration methodsFor:'testing'!

isZero
    ^ self = self class zero
! !

!TimeDuration class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic2/Attic/TimeDuration.st,v 1.28 2007-10-26 14:07:25 cg Exp $'
! !

TimeDuration initialize!