how to get current calendar week

Started by Beat, August 12, 2020, 04:04:43 AM

Previous topic - Next topic

Beat

Hi,
I know it not easy, but how can I calculate the corrent "calendar week".In defintion the first week in the year is the fist week in January which include Thursday.
at the moment I 've not a idea sorry.

regards from SwitzerlandBeat
si tacuisses, philosophus mansisses!! ;-)
if you had remained silent, you would have continued to be a philosopher!!
Wenn du geschwiegen hättest, wärst du ein Philosoph geblieben!!

ChuckC

Please further define what you mean by "calendar week".

January 1, 2020, was a Wednesday.

When I look at a calendar, depending whether it is made to American or European conventions, weeks on the calendar start on Sunday or Monday, respectively.

Are you counting weeks as 7 day periods starting from the first day of the year, or are starting with the block of 7 days that start on a Sunday or Monday and which contains the date 1/1/2020 as your first week of the year?


td

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

There is also a GetWeekOfYear() method using WB/CLR - ObjectClrOption("useany","System.Globalization")


[EDIT]:  you can reference this earlier thread Tony helped with


https://forum.winbatch.com/index.php?topic=2190.msg11383#msg11383


I only mention this as the OP is outside the US and the Calendar 'culture' may be relevant

Beat

Hi all together,
thank's for all the help.

@ ChuckCI'm sorry, but I didn't know the difference between American and European weeks and calendar weeks. For me it is normal first day of a week is Monday,last day is Sunday this seem to be the difference, "but not only this"  ;)
@ td and stanl
Thank you both it seems to be exact what I'm looking for.
I'll try to check the code and also try to understand the code
regards from sunny and hot Switzerland
Beat

si tacuisses, philosophus mansisses!! ;-)
if you had remained silent, you would have continued to be a philosopher!!
Wenn du geschwiegen hättest, wärst du ein Philosoph geblieben!!

stanl

Below I gave it a shot using WB's CLR. It does error saying the GetWeekOfYear method not found, but since I adopted the script from a .Net example, hopefully Tony or Chuck will give it a look
Code (WINBATCH) Select


;using CLR to get current week of year
IntControl(73,1,0,0,0)
Gosub udfs
cCulture = "es-US" ;change as need: i.e. German is de-DE
ObjectClrOption("useany","System.Globalization")
;open the CultureInfo class
oCulture = ObjectClrNew("System.Globalization.CultureInfo",cCulture)
dt  = ObjectClrNew("System.DateTime")
dt=dt.Now ;current timestamp


Calendar = oCulture.Calendar
fmt=oCulture.DateTimeFormat


;wrule="FirstDay,FirstFourDayWeek,FirstFullWeek"
;cRule = ItemExtract(fmt.CalendarWeekRule,wrule,",")


cRule = fmt.CalendarWeekRule
firstDay = fmt.FirstDayOfWeek


;error that method cannot be found
weekOfYear = Calendar.GetWeekOfYear(dt,cRule,firstDay)


Message("Current Week Of Year",weekOfYear)




Exit


:WBERRORHANDLER
geterror()
Message("Error Encountered",errmsg)
Exit


:CANCEL
oCulture=0
new=0
Terminate(@TRUE,"Script Aborted","Cancel Chosen")
Exit




:udfs
#DefineSubRoutine GetTimeformat(culture,code)
IntControl(73,1,0,0,0)
Dt=culture.DateTimeFormat
cal=Dt.NativeCalendarName
results=code:" {":cal:") TimeFormats":@LF
Dn=Dt.DayNames
tmp=""
ForEach d in Dn
   tmp=tmp:d:","
Next
tmp=StrSub(tmp,1,strlen(tmp)-1)


Mn=Dt.MonthNames
tmp1=""
ForEach m in Mn
   tmp1=tmp1:m:","
Next
tmp1=StrSub(tmp1,1,strlen(tmp1)-1)




results=results:"Days of Week: ":tmp:@LF
results=results:"Months: ":tmp1:@LF
wrule="FirstDay,FirstFourDayWeek,FirstFullWeek"
results=results:"CalendarWeekRule: ":ItemExtract(Dt.CalendarWeekRule,wrule,","):@LF


results=results:"FirstDayOfWeek: ":ItemExtract(Dt.FirstDayOfWeek,tmp,","):@LF
results=results:"FullDateTimePattern: ":Dt.FullDateTimePattern:@LF
results=results:"RFC1123Pattern: ":Dt.RFC1123Pattern:@LF
Return(results)


:WBERRORHANDLER
ErrorProcessing(0,1,0,0)
Exit


#EndSubRoutine


#DefineSubRoutine geterror()
   wberroradditionalinfo = wberrorarray[6]
   lasterr = wberrorarray[0]
   handlerline = wberrorarray[1]
   textstring = wberrorarray[5]
   linenumber = wberrorarray[8]
   errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
   Return(errmsg)
#EndSubRoutine




Return



ChuckC

https://docs.microsoft.com/en-us/dotnet/api/system.globalization.calendar.getweekofyear?view=netframework-4.8


I think you have the wrong class type instantiated as "Calendar".  From the documentation reference [see above], it should be an instance of "System.Globalization.Calendar".


stanl

Quote from: ChuckC on August 15, 2020, 06:34:03 AM
https://docs.microsoft.com/en-us/dotnet/api/system.globalization.calendar.getweekofyear?view=netframework-4.8


I think you have the wrong class type instantiated as "Calendar".  From the documentation reference [see above], it should be an instance of "System.Globalization.Calendar".


Thanks.  Guess I got off track as the code associated with the link

// Gets the Calendar instance associated with a CultureInfo. CultureInfo myCI = new CultureInfo("en-US"); Calendar myCal = myCI.Calendar;



makes it look like it is created from CultureInfo and I coded as such.  Looks like a rainy day, and almost finished with season 2 of The Alienist... so can maybe play around.


There is also [supposedly] a System.Globalization.ISOWeek class which would make things easy by just calling GetWeekOfYear(DateTime) - but can't seem to create the Object.


stanl

... and of course Powershell does it with one line of code:   get-date -UFormat %V


[EDIT]: Or select a given data, send to clipboard so can be returned to WB script
get-date -Date "5/1/2020" -UFormat %V | Clip

stanl

Decided not to mess anymore with CLR. Attached perform request based on current date and computer cultureinfo, using WB/Powershell. Script can be modified any number of ways based on parameters for PS Get-Date
Code (WINBATCH) Select


gosub udfs
IntControl(73,1,0,0,0)
BoxOpen("Please Wait","Obtaining Current Week Of Year")
cScript= $"
$d = get-date -UFormat %%V
$d | Clip
exit(1)
$"


;Message("",cScript)  ;uee to check PS input code
                      ; have to use %% for correct WB formatting
PShell()
n = ClipGet()
BoxShut()
Message("Current Week Of Year",n)
Exit


:WBERRORHANDLER
geterror()
Message("Error Encountered",errmsg)
Exit


:udfs
#DefineSubRoutine geterror()
   wberroradditionalinfo = wberrorarray[6]
   lasterr = wberrorarray[0]
   handlerline = wberrorarray[1]
   textstring = wberrorarray[5]
   linenumber = wberrorarray[8]
   errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
   Return(errmsg)
#EndSubRoutine


#DefineSubRoutine PShell()
oNoGo = ObjectType("BOOL",@FALSE)
ObjectClrOption("useany", "System.Management.Automation")
objAutoPs = ObjectClrNew("System.Management.Automation.PowerShell")
oPshell = objAutoPs.Create()
oScope = ObjectType("BOOL",@TRUE)
oPshell.AddScript(cScript,oScope)
objAsync = oPshell.BeginInvoke()


tries=0
BoxText("Invoking Script Command...")
While objAsync.IsCompleted == oNoGo
   TimeDelay(1)
   tries=tries+1
   If tries>10 Then Break
EndWhile


oPShell.EndInvoke(objAsync) 


Return(1)
#EndSubRoutine


Return



td

I know it is a quible but but since you are using the CLR to execute PS you are still messing with it.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

And, unless you are using a feature unique to PowerShell and not the underlying .Net Framework / .Net Standard runtimes, it's less overhead to directly invoke the CLR and use its services than it is to instantiate a captive instance of PowerShell, which must initialize the .Net runtime as well as itself.

td

Making it work using just the Framework depends on addressing the same old problem.  The CLR hands enumeration values to WinBatch as variant integers stripped of their more specific identity.  This presents problems because the CLR is strongly type.  The solution, however, is relatively simple; just give the integer it's specific type back.

Code (winbatch) Select
;using CLR to get current week of year
cCulture = "es-US" ;change as need: i.e. German is de-DE
ObjectClrOption("useany","System.Globalization")

;open the CultureInfo class
oCulture = ObjectClrNew("System.Globalization.CultureInfo",cCulture)
dt  = ObjectClrNew("System.DateTime")
dt=dt.Now ;current timestamp

Calendar = oCulture.Calendar
fmt=oCulture.DateTimeFormat
cRule = fmt.CalendarWeekRule
firstDay = fmt.FirstDayOfWeek

weekOfYear = Calendar.GetWeekOfYear(dt,System.Globalization.CalendarWeekRule:cRule,System.DayOfWeek:firstDay)

Message("Current Week Of Year",weekOfYear)

Exit


And thanks for pointing out another solution for the OP.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on August 16, 2020, 09:55:40 AM
I know it is a quible but but since you are using the CLR to execute PS you are still messing with it.


Yeah! thought I would get flack for that. Thanks for another lesson in .NET types, so basically the original script was right for the wrong reason.




ChuckC

Not to muddy the waters, or necessarily to play the devil's [or is that devel's] advocate for PowerShell, but I know specifically of a case where PowerShell implements a command that does the same thing as two methods in System.IO.Path, GetDirectoryName() & GetFileName(), but does so correctly whereas the .Net Framework implementation fails in a counter intuitively insidious way.  Oh, and just to complicate things, .Net Standard/Core has the same class & methods and they work properly.  The PowerShell command in question is Split-Path.

The scenario is that the path to be split contains a named stream and is of the form "C:\SomeFolder\SomeAdditionalFolder\MyFile.txt:MyStream".

See what happens when you parse out the file name and the parent path using PowerShell, .Net Farmework and .Net Standard.  And maybe for giggles, test out WinBatch's FilePath() & FileRoot(), too.


td

FilePath would return "C:\SomeFolder\SomeAdditionalFolder\" and FileRoot would return "MyFile".
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

Oops!

I meant FileBaseName(), not FileRoot().  However, the point is moot for WinBatch since it actually does the parsing correctly.  I simply meant to toss in the references to WIL functions since WIL contains analogs of the other .Net Framework / .Net Standard & PowerShell functions that perform the same parsing functions.


td

For many years I have been of the opinion that the function names "FileRoot" and "FileBaseName" are unfortunate.  Which does what has tripped me up more time than I care to recount.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on August 16, 2020, 12:24:47 PM
The solution, however, is relatively simple; just give the integer it's specific type back.



If I had tried


cRule = ObjectClrNew( 'System.Int32', fmt.CalendarWeekRule )
firstDay = ObjectClrNew( 'System.Int32', fmt.FirstDayOfWeek )



the GetWeekOfYear() would have still failed. I did notice the use of the ":" to assign the type in the C# examples.

td

Assuming you are referring to casting the parameters to the GetWeekOfYear method, it would be pointless to cast them as "System.Int32". For one thing, the WIL CLR hosting subsystem automatically handles type identification of basic types like integers and strings. The other is that being strongly typed means that one enumeration value being equal to a given integer is not the same as the integer itself nor another enumeration's value with the same integer value.  In other words, the enumerations are the type and not the integers used to represent them. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

KeithW

As of today, 8/17/20 @ 23:55  I noted that both of the last scripts yielded differing answers 34 vs 33 for the week number... which is correct?

Keith

KeithW

I should have been a bit more specific as my 23:55  was CDT if that matters....    Keith

stanl

Quote from: KeithW on August 17, 2020, 09:57:58 PM
As of today, 8/17/20 @ 23:55  I noted that both of the last scripts yielded differing answers 34 vs 33 for the week number... which is correct?

Keith


If you were referring to (1) the script invoking Powershell (2) Tony's fix for the .NET script - I just ran them 10/18 5:29 EDT and both yielded 34

td

The ISO standard for this sort of thing agrees with today (8/18/2020) being part of week 34. I also get that result with both scripts.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade