I'm wondering what would cause this. Is it possible that there is simply no
record of when the user last logged in?! I have tried to understand the
script but am having a bit of trouble. Here is the code:
----------
'Option Explicit
Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser
Dim strBase, strFilter, strAttributes, lngHigh, lngLow
' New variables added to track if account disabled.
Dim objList2, lngFlags, blnDisabled
Dim strOutputFile, objReport, objFSO
Const ADS_UF_ACCOUNTDISABLE = &H02
' Use a dictionary object to track latest lastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare
' Dictionary object to track if user accounts disabled.
Set objList2 = CreateObject("Scripting.Dictionary")
objList2.CompareMode = vbTextCompare
Set objFSO = CreateObject("Scripting.FileSystemObject")
strOutputFile = "c:\Scripts\Result\last_login_times.txt"
Set objReport = objFSO.OpenTextFile(strOutputFile, 2, True, 0)
' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(lngBiasKey)) = "LONG" Then
lngBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False
Set objRecordSet = objCommand.Execute
' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
Set objDC = _
GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
ReDim Preserve arrstrDCs(k)
arrstrDCs(k) = objDC.DNSHostName
k = k + 1
objRecordSet.MoveNext
Loop
' Retrieve lastLogon attribute for each user on each Domain Controller.
For k = 0 To Ubound(arrstrDCs)
strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
strFilter = "(&(objectCategory=person)(objectClass=user))"
strAttributes = "distinguishedName,lastLogon"
strQuery = strBase & ";" & strFilter & ";" & strAttributes _
& ";subtree"
objCommand.CommandText = strQuery
On Error Resume Next
Err.Clear
Set objRecordSet = objCommand.Execute
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Wscript.Echo "Domain Controller not available: " & arrstrDCs(k)
Else
On Error GoTo 0
Do Until objRecordSet.EOF
strDN = objRecordSet.Fields("distinguishedName")
lngDate = objRecordSet.Fields("lastLogon")
On Error Resume Next
Err.Clear
Set objDate = lngDate
If Err.Number <> 0 Then
Err.Clear
dtmDate = #1/1/1601#
Else
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
If lngLow < 0 Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0 ) Then
dtmDate = #1/1/1601#
Else
dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow)/600000000 - lngBias)/1440
End If
End If
On Error GoTo 0
If objList.Exists(strDN) Then
If dtmDate > objList(strDN) Then
objList(strDN) = dtmDate
End If
Else
objList.Add strDN, dtmDate
End If
objRecordSet.MoveNext
Loop
End If
Next
---------------------
--
Robert Cohen
A legend in his own mind
--
"Ziek" <Pe...@start.net> wrote in message
news:e$#UiGDDE...@TK2MSFTNGP09.phx.gbl...
like Robert said, the "lastLogon" attribute is only written on the Domain Contoller the user actually logged on, and this attribute does not get replicated. So, to really check your users for this attribute, you must collect the information from all your DCs, then get the lastest date as the "real" last logon time of this user.
Please think about using the "lastLogonTimestamp" attribute instead. This attribute is updated frequently and gets replicated to all other DCs, so that is doesn't matter which DC you's asking. The only pitfall might be that it might not show the EXACT last logon time, but it's easier to retrieve.
LastLogon is stored as Integer8, meaning a 64-bit number (8 bytes). This
large number represents the number of 100-nanosecond intervals since 12:00
AM, January 1, 1601. (I'm sure long ago some coder wanted to avoid the date
February 29, 1600. 1600 (and 2000) are leap year exceptions since all other
years ending in 00 are not leap years.) Anyway, any date that displays as
1/1/1601 is really the "zero" date, meaning "never". If the lastLogon
attribute has a value of zero, this translates to 1/1/1601.
You could code the function that converts lastLogon to a date to return
"Never" for zero dates. However, since lastLogon is not replicated you need
to compare the date retrieved on each DC to get the largest (latest) date.
The comparison would raise an error if the date were "Never". After you have
finished querying every DC you could test for this date and output "Never".
In the code you posted, the dictionary object objList retains the largest
lastLogon date for each user. The loop to output the dates for all users
would be:
' Output latest lastLogon date for each user.
For Each strUser In objList
Wscript.Echo strUser & " ; " & objList(strUser)
Next
It is at this point that you could test for the zero date. For example, you
could modify this loop as follows:
' Output latest lastLogon date for each user.
For Each strUser In objList
If objList(strUser) = #1/1/1601# Then
Wscript.Echo strUser & " ; Never"
Else
Wscript.Echo strUser & " ; " & objList(strUser)
End If
Next
--
Richard
Microsoft MVP Scripting and ADSI
HilltopLab web site - http://www.rlmueller.net
--
"Ziek" <Pe...@start.net> wrote in message
news:e$%23UiGDD...@TK2MSFTNGP09.phx.gbl...
besides 1600 and 2000, if the year ends with 00, it is not leap year? So in
2200, there will not be a leap year even though it falls on a leap year?
Yes. In fact, 1900 was not a leap year. The rule is if the year is divisible
by 100 it is not a leap year, unless it is also divisible by 400. 2400 will
be a leap year, but 2100, 2200, and 2300 are not. It's because there are
365.2422 (about) days per year, not 365.25.
Richard
"Robert Cohen" <do...@want.spam.com> wrote in message
news:OZhjlgD...@tk2msftngp13.phx.gbl...
Also, is my code checking all domain controllers, or is it only querying
one?
"Richard Mueller [MVP]" <rlmuelle...@ameritech.NOSPAM.net> wrote in
message news:e#IkODEDE...@TK2MSFTNGP11.phx.gbl...
"Stivie S." <stefan....@computacenter.com> wrote in message
news:4710070F-5182-4A30...@microsoft.com...
Option Explicit
Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser
Dim strBase, strFilter, strAttributes
' Use a dictionary object to track latest LastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare
' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(lngBiasKey)) = "LONG" Then
lngBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("ConfigurationNamingContext")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
strBase = "<LDAP://" & strConfig & ">"
strFilter = "(ObjectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False
Set objRecordSet = objCommand.Execute
' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
Set objDC = _
GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
ReDim Preserve arrstrDCs(k)
arrstrDCs(k) = objDC.DNSHostName
k = k + 1
objRecordSet.MoveNext
Loop
' Retrieve LastLogon attribute for each user on each Domain Controller.
For k = 0 To Ubound(arrstrDCs)
strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
strFilter = "(&(ObjectCategory=person)(ObjectClass=user))"
strAttributes = "DistinguishedName,LastLogon"
strQuery = strBase & ";" & strFilter & ";" & strAttributes _
& ";subtree"
objCommand.CommandText = strQuery
On Error Resume Next
Err.Clear
Set objRecordSet = objCommand.Execute
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Wscript.Echo "Domain Controller not available: " & arrstrDCs(k)
Else
On Error GoTo 0
Do Until objRecordSet.EOF
strDN = objRecordSet.Fields("DistinguishedName")
lngDate = objRecordSet.Fields("LastLogon")
On Error Resume Next
Err.Clear
Set objDate = lngDate
If Err.Number <> 0 Then
Err.Clear
dtmDate = #1/1/1601#
Else
If (objDate.HighPart = 0) And (objDate.LowPart = 0 ) Then
dtmDate = #1/1/1601#
Else
dtmDate = #1/1/1601# + (((objDate.HighPart * (2 ^ 32)) _
+ objDate.LowPart)/600000000 - lngBias)/1440
End If
End If
On Error GoTo 0
If objList.Exists(strDN) Then
If dtmDate > objList(strDN) Then
objList(strDN) = dtmDate
End If
Else
objList.Add strDN, dtmDate
End If
objRecordSet.MoveNext
Loop
End If
Next
' Output latest LastLogon date for each user.
For Each strUser In objList
Wscript.Echo strUser & " ; " & objList(strUser)
Next
' Clean up.
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing
--
Robert Cohen
A legend in his own mind
--
"Ziek" <Pe...@start.net> wrote in message
news:OcVP02FD...@TK2MSFTNGP11.phx.gbl...
12:00 AM is confusing in an internationally-distributed newsgroup; you
mean 00:00:00 or 0000h. Moreover, the start time is not any old local
1601-01-01 00:00:00, but is that in UTC/GMT.
> (I'm sure long ago some coder wanted to avoid the date
>February 29, 1600. 1600 (and 2000) are leap year exceptions since all other
>years ending in 00 are not leap years.)
Rather short-termist ... years 100..1500 were everywhere Leap, and 2400,
2800, ... are intended to be so.
Moreover, on Historical 1700-02-29, William Penn's son John "The
American" was born, in Philadelphia; the first by his second wife. In
truth, in the British Empire, Historical 1700 was a Leap Year.
It is necessary to include the word "Gregorian" there.
> Anyway, any date that displays as
>1/1/1601 is really the "zero" date, meaning "never".
is probably, or in this context is
> If the lastLogon
>attribute has a value of zero, this translates to 1/1/1601.
Which IMHO it should not do, for those West of the Atlantic Ocean;
1601-01-01 00:00:00 UTC/GMT was during the previous afternoon/evening in
the Americas. It is possible that special treatment is given, if
Americans really see 1601 Jan 1.
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
I guess the term "unsuccessful logon" carries with it the invalid
implication that it was a logon of some sort, specifically the unsuccessful
sort. In fact, an unsuccessful logon is no logon at all, and is not counted
as a logon on the domain controllers.
> An unsuccessful attempt to logon, meaning,
> incorrect password, would not be treated as a valid last logon date,
right?
No. But it would be "counted" as a bad password by the domain controller,
and the most recent such attempt would be logged as such in a different date
attribute (badpassworddate or badpasswordtime, I think).
> Also, is my code checking all domain controllers, or is it only querying
> one?
It appears to be attempting to query each domain controller.
/Al
Exactly.
> Moreover, the start time is not any old local
> 1601-01-01 00:00:00, but is that in UTC/GMT.
Keep that thought in mind...
> > (I'm sure long ago some coder wanted to avoid the date
> >February 29, 1600. 1600 (and 2000) are leap year exceptions since all
other
> >years ending in 00 are not leap years.)
>
> Rather short-termist ... years 100..1500 were everywhere Leap, and 2400,
> 2800, ... are intended to be so.
100 was a leap year? When Dionysius Exiguus selected in the sixth century
(somewhat later than 100, by my reckoning) the birth of Christ as the
initial epoch of the Christian calendar, did he at that time declare the
leap year rule? Or did that come later? Or are you referring to the year 100
AD - Anno Diocletian, the system previously in use, which was offset from
the Christian calendar by about 284 years?
Seems a little facetious to quibble about a day here or there back in a time
before they knew it was the year 100, when there are perhaps years or even
centuries missing in the history of the world. Have you seen any records of
birth dated Feb 29th, 100? Or, for that matter, any other day in that month?
> Moreover, on Historical 1700-02-29, William Penn's son John "The
> American" was born, in Philadelphia; the first by his second wife. In
> truth, in the British Empire, Historical 1700 was a Leap Year.
Interesting, then, that the legal code of the US does not declare which
calendar is the official one. It seems that they use the Gregorian calendar
as a result of an act of Parliament of the United Kingdom in 1751.
I have no doubt that, if you search the archives hard enough, you will find
records of birth dated February 30th. That doesn't mean there was ever such
a date, just evidence that people make mistakes.
> It is necessary to include the word "Gregorian" there.
>
> > Anyway, any date that displays as
> >1/1/1601 is really the "zero" date, meaning "never".
>
> is probably, or in this context is
Most probably, the logon date is initialized to contain a zero value when
the account is replicated to the domain controller. This isn't considered as
equivalent to the date 1601-01-01, unless someone applies the date
calculation without regard to boundary issues. It is not the date
calculating out to 1601-01-01 that flags an unused account so much as the
zero value from which this might be calculated.
> > If the lastLogon
> >attribute has a value of zero, this translates to 1/1/1601.
>
> Which IMHO it should not do, for those West of the Atlantic Ocean;
> 1601-01-01 00:00:00 UTC/GMT was during the previous afternoon/evening in
> the Americas. It is possible that special treatment is given, if
> Americans really see 1601 Jan 1.
Don't forget (as you stated above) that the domain stores its dates relative
to UCT. Also, if one of my users in the next time zone to the east has never
logged on, it cannot truly be said that his logon predated that of someone
in my current time zone who likewise has never logged on. Never is never in
any timezone. The problem is thinking that never and infinity actually exist
somewhere on a linear timeline.
/Al
The date/time values are stored in UTC (what used to be called GMT). I
normally correct for the local time zone to convert to local time. However,
I do not correct the "zero" date/time, and instead leave it as 1/1/1601
(because it looks silly to be a few hours off, especially if this moves the
zero date into another century). I'll agree that 00:00:00 is probably
clearer than 12:00 AM.
>
> > (I'm sure long ago some coder wanted to avoid the date
> >February 29, 1600. 1600 (and 2000) are leap year exceptions since all
other
> >years ending in 00 are not leap years.)
>
> Rather short-termist ... years 100..1500 were everywhere Leap, and 2400,
> 2800, ... are intended to be so.
You're right. Before about 45 BC, years consisted of 12 months of 30 days
each, with 5 days extra tacked on at the end. Starting about 45 BC they
tacked on 6 extra days every fourth year (the Julian calendar). So, from
then until about 1582 every 4th year was a leap year. However, the calendar
was so screwed up by that time (Pope Gregory XIII didn't like Easter
creeping into summer), they actually skipped 10 days. October 4, 1582 was
followed by October 15. Thereafter, the Gregorian calendar had years
divisible by 100 not leap years unless they were also divisible by 400.
However, some parts of the world did not adopt the Gregorian calendar until
the early 1900's.
>
> Moreover, on Historical 1700-02-29, William Penn's son John "The
> American" was born, in Philadelphia; the first by his second wife. In
> truth, in the British Empire, Historical 1700 was a Leap Year.
My reference says Great Britain (and the American colonies) adopted the
Gregorian calendar in 1752. September 2, 1752 was followed by September 14.
Russia switched in 1918, by which time the correction was 13 days.
>
> It is necessary to include the word "Gregorian" there.
>
> > Anyway, any date that displays as
> >1/1/1601 is really the "zero" date, meaning "never".
>
> is probably, or in this context is
>
> > If the lastLogon
> >attribute has a value of zero, this translates to 1/1/1601.
>
> Which IMHO it should not do, for those West of the Atlantic Ocean;
> 1601-01-01 00:00:00 UTC/GMT was during the previous afternoon/evening in
> the Americas. It is possible that special treatment is given, if
> Americans really see 1601 Jan 1.
Technically, the zero date/time is 1601-01-01 00:00:00 UTC.
And, there is no provision in Microsoft's scheme to account for leap
seconds. Since the length of the year fluctuates, they periodically add or
subtract a second (up to twice a year).
I object to 1/1/1601 on the grounds that I cannot tell which "1" represents
the month, and which represents the day.
> > > (I'm sure long ago some coder wanted to avoid the date
> > >February 29, 1600. 1600 (and 2000) are leap year exceptions since all
> other
> > >years ending in 00 are not leap years.)
> >
> > Rather short-termist ... years 100..1500 were everywhere Leap, and 2400,
> > 2800, ... are intended to be so.
>
> You're right. Before about 45 BC, years consisted of 12 months of 30 days
> each, with 5 days extra tacked on at the end. Starting about 45 BC they
> tacked on 6 extra days every fourth year (the Julian calendar). So, from
> then until about 1582 every 4th year was a leap year. However, the
calendar
> was so screwed up by that time (Pope Gregory XIII didn't like Easter
> creeping into summer), they actually skipped 10 days. October 4, 1582 was
> followed by October 15. Thereafter, the Gregorian calendar had years
> divisible by 100 not leap years unless they were also divisible by 400.
> However, some parts of the world did not adopt the Gregorian calendar
until
> the early 1900's.
Still begs the question as to whether something happening after the fact can
change what has already happened. Since the Gregorian calendar was adopted
centuries after the year 100, would the people around back then have even
known it was a leap year, let alone that the year actually was 100? Suppose
someone was born on the fifth day of festivus in the year that we now call
100, and that that date corresponds with our Feb 29th. Can we state with
any credibility whatsoever that that person was not born on the fifth day of
festivus, but rather on Feb 29th?
Suppose that at some future date a different calendar was adopted in which
February had only 26 days, and extrapolated it into the past. Would that
mean that we have never experienced a February 29th? And what if that
calendar system stated that every year whose first digit was half of its
last digit was a sidestep year. Would that mean, retroactively, that this is
a sidestep year we are in now?
> >
> > Moreover, on Historical 1700-02-29, William Penn's son John "The
> > American" was born, in Philadelphia; the first by his second wife. In
> > truth, in the British Empire, Historical 1700 was a Leap Year.
>
> My reference says Great Britain (and the American colonies) adopted the
> Gregorian calendar in 1752. September 2, 1752 was followed by September
14.
> Russia switched in 1918, by which time the correction was 13 days.
My reference says it was 1751 - so much for accuracy in date measurement. My
reference (http://astro.nmsu.edu/~lhuber/leaphist.html) also states that the
acceptance of the Gregorian calendar as an international standard spanned
three centuries. Let's hope we are not still arguing this stuff in 2204.
> > It is necessary to include the word "Gregorian" there.
> >
> > > Anyway, any date that displays as
> > >1/1/1601 is really the "zero" date, meaning "never".
> >
> > is probably, or in this context is
> >
> > > If the lastLogon
> > >attribute has a value of zero, this translates to 1/1/1601.
> >
> > Which IMHO it should not do, for those West of the Atlantic Ocean;
> > 1601-01-01 00:00:00 UTC/GMT was during the previous afternoon/evening in
> > the Americas. It is possible that special treatment is given, if
> > Americans really see 1601 Jan 1.
>
> Technically, the zero date/time is 1601-01-01 00:00:00 UTC.
>
> And, there is no provision in Microsoft's scheme to account for leap
> seconds. Since the length of the year fluctuates, they periodically add or
> subtract a second (up to twice a year).
Hence the need to avoid an over-reliance on the lowly BIOS clock.
/Al
"Robert Cohen" <do...@want.spam.com> wrote in message
news:u7Zf4hGD...@tk2msftngp13.phx.gbl...
--
Robert Cohen
A legend in his own mind
--
"Ziek" <Pe...@start.net> wrote in message
news:u0G6DkQ...@tk2msftngp13.phx.gbl...
>100 was a leap year? When Dionysius Exiguus selected in the sixth century
>(somewhat later than 100, by my reckoning) the birth of Christ as the
>initial epoch of the Christian calendar, did he at that time declare the
>leap year rule? Or did that come later? Or are you referring to the year 100
>AD - Anno Diocletian, the system previously in use, which was offset from
>the Christian calendar by about 284 years?
AD 100 was a leap year, in accordance with the decree of Julius Caesar
(advised by Sosigenes) in about BC 46. Of course, it was not at the
time known that the year would later be called AD 100. OTOH, AD 4 was
not Leap.
ADio 100 was a century and a half before Little Denis; LD had no effect
on Leap Years. He, of course, would nave written not 100 but C.
>Seems a little facetious to quibble about a day here or there back in a time
>before they knew it was the year 100, when there are perhaps years or even
>centuries missing in the history of the world.
No, AIUI there is a continuous date scale running back well into Old
Testament times. There are many historical events whose exact position
on that scale is uncertain, of course - the death-date of Shergar, for
example.
Moreover, errors can have many consequences. When some chronologically
under-informed programmer, maybe at Lotus, introduced a daycount
intended to start with 1900-01-01 = Day 1, he or she forgot about the
absence of Gregorian 1900-02-29. That is why the zero of the Delphi
TDateTime type (etc.), by inheritance for compatibility, is 1899-12-30
0000h local.
A pity that he did not use a C-style day index starting at zero, since
that peculiarity would have cancelled out the calendar error and we'd
have ended up with Jan 1st = Day 1.
>> Moreover, on Historical 1700-02-29, William Penn's son John "The
>> American" was born, in Philadelphia; the first by his second wife. In
>> truth, in the British Empire, Historical 1700 was a Leap Year.
>
>Interesting, then, that the legal code of the US does not declare which
>calendar is the official one. It seems that they use the Gregorian calendar
>as a result of an act of Parliament of the United Kingdom in 1751.
Yes; the British Parliament had authority over the American Colonies,
and, explicitly or otherwise, existing law was doubtless inherited by
the States unless formally overridden. However, the Act specifically
refers to regions such as the American Colonies, but omits Australia and
New Zealand. They, therefore, should each have an Act of their own.
>I have no doubt that, if you search the archives hard enough, you will find
>records of birth dated February 30th. That doesn't mean there was ever such
>a date, just evidence that people make mistakes.
There was such a date, in 1712. It came between Feb 29 and Mar 1. It
was CJD 2346425 and mostly MJD -53576. It was a Friday.
>Don't forget (as you stated above) that the domain stores its dates relative
>to UCT. Also, if one of my users in the next time zone to the east has never
>logged on, it cannot truly be said that his logon predated that of someone
>in my current time zone who likewise has never logged on. Never is never in
>any timezone. The problem is thinking that never and infinity actually exist
>somewhere on a linear timeline.
A non-user has, we believe, a record containing zero. That means
[proleptic] Gregorian A.D. 1601-01-01 00:00:00.0000000 UTC,
independently of location. That time was proleptic Gregorian New York
1600-12-31 19:00:00 and in Vancouver 1600-12-31 16:00:00.
Not quite correct.
In about 45 BC they decided to make every fourth year longer, with
immediate effect (it seems uncertain whether 45 BC was actually, rather
than potentially, Leap).
But the arcane art of counting up to four was not at the time
sufficiently well understood in the responsible temples, and the first
[baker's?] dozen of Leap Years were at three-year intervals. There was
then no Leap Year between 9 BC and 8 AD.
Readers appear not to have observed what lies below.