In the provided code snippet the t2 time initialized explicitly to 0 UTC is negative when printed.
I don't understand why that is, could someone explain it for me?
func main() {
const IsoDatetimeFormat = "2006-01-02T15:04:05"
t1 := time.Time{}
t2 := time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
fmt.Println(t1.Format(IsoDatetimeFormat))
fmt.Println(t2.Format(IsoDatetimeFormat))
}
Output:
0001-01-01T00:00:00
-0001-11-30T00:00:00
playground link
time.Time documents that the zero value for time.Time represents / means January 1, year 1, 00:00:00.000000000 UTC:
The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. As this time is unlikely to come up in practice, the IsZero method gives a simple way of detecting a time that has not been initialized explicitly.
There is no year 0, so if you use year, month and day values smaller than 1, they will roll over to negative. The time package accepts and normalizes values given outside of valid ranges. Quoting from time.Date():
The month, day, hour, min, sec, and nsec values may be outside their usual ranges and will be normalized during the conversion. For example, October 32 converts to November 1.
The zero value to be January 1, year 1 was an arbitrary choice. As to reasoning why year 1 was chosen:
// The zero value for a Time is defined to be
// January 1, year 1, 00:00:00.000000000 UTC
// which (1) looks like a zero, or as close as you can get in a date
// (1-1-1 00:00:00 UTC), (2) is unlikely enough to arise in practice to
// be a suitable "not set" sentinel, unlike Jan 1 1970, and (3) has a
// non-negative year even in time zones west of UTC, unlike 1-1-0
// 00:00:00 UTC, which would be 12-31-(-1) 19:00:00 in New York.
Related
I have to solve this real problem, it seemed trivial to me at first but I am having difficulty and I don't have much time to solve it. I would like to solve it possibly with python so then I can print the result to a csv.
This is the problem:
Problem
7 employees must divide the work shifts (M,A,N, morning afternoon and night) over 7 weeks.
Each day of the 49 days must have a different employee for each shift.( e.g. day1: M:employee 1, A:employee 3, N:employee 6 )
Each employee works weekday/time slot only 1 time in the 49-day cycle (e.g. employee 1 does 1 Monday morning, 1 Monday afternoon, 1 Monday night, 1 Tuesday morning etc)
If an employee works a night shift, it cannot work shifts on the next 2 days.
Mapping shift (M, A, N) to (0, 1, 2) with variable s, day (Monday, Tuesday, ..., Sunday) to (0, 1, ..., 6) with variable d, and week in variable w, you can use the formula (w+d-s)%7+1 to get the employee assigned to shift w,d,s (% is the modulo operator).
(in some languages like C++, you might have to add 7 in the parentheses if modulo of negative numbers outputs a negative number)
I'm trying to process some WMI counters using Go (as part of learning Go) and am trying to figure out how to generate the necessary time object.
The base is the Win32 epoch (1601-01-01) and a sample timestamp is 13224382394716547600ns (or rather, 132243823947165476 100ns units).
Here's what I've tried:
test 1 (add nanoseconds)
win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_1 := win_epoch.Add(13224382394716547600*time.Nanosecond)
test 2 (add days)
win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_2 := win_epoch.AddDate(0,0,(132243823947165476/10000000 / 3600 / 24))
current_ts_1 in test 1 fails with an overflow error.
current_ts_2 in test 2 only gives me resolution at the date level.
Ideally I'd be able to get the millisecond resolution on this. Does there exist a way to not overflow the Duration being passed to .Add() and still get this resolution?
This conversion requires dealing with some huge numbers. Your example time
13,224,382,394,716,547,600 is too big to fit into an int64 (max 9,223,372,036,854,775,807) but does fit into a unit64.
You cannot use time.Duration when dealing with this because that is a int64 nanosecond count; as the docs say "The representation limits the largest representable duration to approximately 290 years". This is why your first attempt fails.
However there is another way of creating a time that will work better here func Unix(sec int64, nsec int64) Time. This takes data in the unix format and this is the time since January 1, 1970 UTC (or 11644473600000000000 represented as ns since the windows epoch).
Using this information it's possible to perform the conversion:
func main() {
const unixTimeBaseAsWin = 11644473600000000000 // The unix base time (January 1, 1970 UTC) as ns since Win32 epoch (1601-01-01)
const nsToSecFactor = 1000000000
timeToConvert := uint64(13224382394716547600)
unixsec := int64(timeToConvert - unixTimeBaseAsWin ) / nsToSecFactor
unixns := int64(timeToConvert % nsToSecFactor)
time := time.Unix(unixsec, unixns)
fmt.Println(time.Local())
}
Note: I have checked this with a few figures but would suggest further testing before you rely upon it.
I would like to calculate the difference between a pair of DateTimes that is rounded to the nearest second or minute.
initial = now()
println(typeof(initial))
sleep(12)
final = now()
difference = final - initial
println(typeof(difference))
gives
DateTime
Base.Dates.Millisecond
The latter type is pretty difficult to use since almost all convenience types are for DateTimes. What is the recommend way to convert difference to seconds or fractional minutes? Is this possible without dropping down to integers? I would prefer to avoid that since it is more error prone.
Since difference represents a duration between dates rather than a particular time, it makes sense for it to just be a duration in milliseconds. Additionally, DateTime and Base.Dates.Millisecond objects are internally represented with an Int64, so everything's already an integer.
julia> moment = now()
2016-12-22T22:54:57.393
julia> dump(moment)
DateTime
instant: Base.Dates.UTInstant{Base.Dates.Millisecond}
periods: Base.Dates.Millisecond
value: Int64 63618130497393
julia> dump(now()-moment)
Base.Dates.Millisecond
value: Int64 29820
Divide the value in milliseconds by 1000 to get seconds, or by 60,000 to get minutes. Use round() to round to the nearest second or minute.
julia> d = (now() - moment).value/60_000
3.9330833333333333
julia> e = round(d)
4.0
Then multiply by 1000 or 60,000 and feed it back into Dates.Millisecond to turn the rounded figure back into the appropriate object:
julia> Dates.Millisecond(60_000e)
240000 milliseconds
Rounding a Date or DateTime object to a given time interval is much simpler, as you can just use round() according to the documentation and it will dispatch to a relevant method:
julia> floor(Date(1985, 8, 16), Dates.Month)
1985-08-01
julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15))
2013-02-13T00:45:00
julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day)
2016-08-07T00:00:00
How can I find the time difference in seconds between two dates in prolog?
datetime(2001,03,04,23,00,32).
datetime(2001,03,04,23,01,33).
timediff(D1,D2,Sec).
Sec=61
SWI-Prolog offers several predicates that convert human-readable time representations into seconds from Epoch (at 1970-01-01). Having the time represented as a number of seconds turns the difference calculation into a simple subtraction operation. For example:
timediff(DateTime1, DateTime2, Sec) :-
date_time_stamp(DateTime1, TimeStamp1),
date_time_stamp(DateTime2, TimeStamp2),
Sec is TimeStamp2 - TimeStamp1.
Usage:
?- timediff(date(2001, 03, 04, 23, 0, 32, 0, -, -),
date(2001, 03, 04, 23, 1, 33, 0, -, -), Sec).
Sec = 61.0.
This gets a little awkward what with the months not being the same length and leap years having extra days.
To start you off, I'm going to give you a version of a predicate that will only take into account hours, minutes, and seconds:
timediff(time(Hours1, Minutes1, Seconds1), time(Hours2, Minutes2, Seconds2), Seconds) :-
Seconds is Seconds1-Seconds2 + 60*(Minutes1-Minutes2 + 60*(Hours1-Hours2)).
If you could run convert_time/2 or convert_time/8 backwards, this process would be much easier, as it would allow you to use the operating system's time conversion routines instead of writing your own.
I'm using a CartesianChart with a DateTimeAxis to display weekly data in a Flex application. When I set dataUnits="weeks" and labelUnits="weeks" on the DateTimeAxis, it automatically places each major tick on a Sunday. However, I would like to provide users with the option of beginning the week on a Sunday or a Monday. How can I ask the DateTimeAxis to instead place the major ticks on a Monday (or some other day of week)?
For example, if the user is looking at total sum of something over the week, and requests that weeks start on a Sunday, the Series data would look like:
x: Date(July 11, 2010) y: 25
x: Date(July 18, 2010) y: 30
x: Date(July 25, 2010) y: 32
etc.
If the weeks start on a Monday, the Series data would instead look like:
x: Date(July 12, 2010) y: 22
x: Date(July 19, 2010) y: 33
x: Date(July 26, 2010) y: 29
etc.
With the second data set, the major ticks are still on July 11, July 18, July 25, etc. but the bars are slightly shifted off-center from the major ticks.
Thanks!
I looked at the code of DateTimeAxis class and I'm almost sure you can't do what you want. If "alignLabelsToUnits" property is set to true (default) then labels are created by rounding Series data dates to appropriate units. In your case (weeks) it looks like this:
case "weeks":
d[hoursP] = 0;
d[minutesP] = 0;
d[secondsP] = 0;
d[millisecondsP] = 0;
if (d[dayP] != 0)
d[dateP] = d[dateP] + (7 - d[dayP]);
break;
So as you can see, it checks if processed date is first day of the week (hard-coded 0), and if it is not, it's changed to be such.
To achieve the behavior you seek, you'd probably have to override function for label creation and write another one for date rounding, as the default rounding function is declared private.
Even though you specify weeks, DateTimeAxis may still be using the hours and minutes values of the newly created date objects. You can format the date to set these to zero. Have a look at http://www.munkiihouse.com/?p=69, mention setting displayLocalTime=”true” in DateTimeAxis tag. Let us know if it works man