Konwersja daty do formatu Daty tygodniowej, zgodnie z normą ISO 8601.
ISO 8601 to międzynarodowa norma ISO określająca sposób zapisu daty i czasu. W standardzie tym używa się sformatowanych ciągów znaków ustawionych w porządku od najbardziej znaczących (rok) do najmniej znaczących (dni, sekundy lub ich części). Norma określa numeryczny format daty i czasu (bez używania nazw miesięcy, dni, tygodni i literowych oznaczeń czasu przed lub po południu).
Na stronie Głównego Urzędu Miar
Numerowanie tygodni w roku
czytamy, że:
- Tydzień jest to okres 7 dni,
- Poniedziałek jest pierwszym dniem tygodnia kalendarzowego (ze względu na łatwiejsze rozliczenia handlowe i finansowe)
- Pierwszym tygodniem kalendarzowym w obrębie danego roku jest tydzień zawierający pierwszy czwartek tego roku
Oznacza to, że:
- Tygodnie są numerowane kolejno w obrębie danego roku,
- Tydzień posiada numer porządkowy w obrębie tego roku kalendarzowego, w którym zawierają się przynajmniej 4 dni tego tygodnia,
- Ostatnim tygodniem kalendarzowym w obrębie danego roku jest tydzień zawierający ostatni czwartek tego roku,
- Końcowe i początkowe dni danego roku kalendarzowego mogą należeć odpowiednio do pierwszego tygodnia roku następnego lub do ostatniego tygodnia roku poprzedniego,
- Przykładowo:
dni 1 – 3 stycznia 2010 roku należą jeszcze do 53 tygodnia 2009 roku,
a dni 4 – 10 stycznia 2010 roku należą do 1 tygodnia 2010 roku.
Data tygodniowa
Data tygodniowa zapisywana jest w formacie YYYY-Www-D
- YYYY - rok zapisywany jest za pomocą czterech cyfr
- Www - numer tygodnia poprzedzony jest zazwyczaj prefiksem W. Oznaczany jest zawsze dwiema cyframi: od 01 do 52 lub 53
- Dzień oznaczany jest jedną cyfrą: od 1 (poniedziałek) do 7 (niedziela).
' Pobiera:
' • datData - data do przekonwertowania na format ISO
' • strSeparatorDaty - separator daty, domyślnie [-] myślnik
' • strPrefixTygodnia - prefix przed dwucyfrowym numerem tygodnia, domyślnie [W]
' Zwraca:
' Przy powodzeniu zwraca sformatowaną datę tygodniową (ISO-8601 )
' w postaci "YYYY-Www-D"
' Poszczególne elementy daty opcjonalnie są rozdzielone separatorem daty
' przekazanym w argumencie strSeparatorDaty
' Przy niepowodzeniu zwraca ciąg zerowej długości.
Public Function funDataTygodniowaISO8601(datData As Date, _
Optional strSeparatorDaty As String = "-", _
Optional strPrefixTygodnia As String = "W") As String
Dim intRok As Integer
Dim intTydzien As Integer
Dim intTydzienNastepny As Integer
Dim intDzien As Integer
' pobierz rok
intRok = Year(datData)
' pobierz numer tygodnia:
' vbMonday - tydzień zaczyna się od Poniedziałku,
' vbFirstFourDays - pierwszy tydzień roku musi zawierać co najmniej cztery dni
intTydzien = DatePart("ww", datData, vbMonday, vbFirstFourDays)
' pobierz numer dnia w tygodniu (licząc od poniedziałku)
intDzien = WeekDay(datData, vbMonday)
If Month(datData) = 12 And intTydzien = 1 Then
intRok = intRok + 1
ElseIf (Month(datData) = 1 And (intTydzien = 52 Or intTydzien = 53)) Then
intRok = intRok - 1
End If
funDataTygodniowaISO8601 = CStr(intRok) & strSeparatorDaty & _
strPrefixTygodnia & Format$(intTydzien, "00") & _
strSeparatorDaty & CStr(intDzien)
MsgBox "UWAGA." & vbNewLine & _
"Funkcja funDataTygodniowaISO8601 działa nieprawidłowo !" & vbNewLine & _
"W tej postaci NIE należy jej używać do jakichkolwiek obliczeń!", vbCritical
End Function
' poniżej przykład jak wywołać funkcję: funDataTygodniowaISO8601 (...)
Private Sub cmdTest_Click()
Dim strDataISO As String
Dim dtData As Date
dtData = CDate("3 stycznia 2010")
'prawidłowo powinniśmy przekazać datę po "amerykańsku" #1/3/2010#
strDataISO = funDataTygodniowaISO8601(dtData, "-")
MsgBox "3 stycznia 2010" & " => " & strDataISO
dtData = CDate("31 grudnia 2007")
strDataISO = funDataTygodniowaISO8601(dtData, "-")
MsgBox "31 grudnia 2007" & " => " & strDataISO
End Sub
Po wywołaniu funkcji funDataTygodniowaISO8601 (...), dla dwóch nieprzypadkowych dat, na ekranie w oknach komunikatu widzimy zwracane przez funkcję wyniki:
Wyświetlany format daty tygodniowej jest poprawny, ale zwracany wynik przez funkcję funDataTygodniowaISO8601 (...) jest prawidłowy dla daty 3 stycznia 2010 r. (pierwsze okienko komunikatu).
Dla daty 31 grudnia 2007 roku, zwracany wynik jest nieprawidłowy.
Po sprawdzeniu na kalendarzu daty dla której zwracany jest nieprawidłowy wynik daty tygodniowej ISO-8601, od razu widzimy, że dzień 31-grudnia 2007 r. powinien być 1-szym dniem, 1-szego tygodnia 2008 roku, ponieważ 1-szy tydzień roku 2008 ma co najmniej 4 dni (zawiera czwartek). Zapis daty tygodniowej powinien mieć postać: 2008-W01-1
tak jak widać w oknie komunikatu po prawej stronie.
Ku przestrodze, w kodzie umieściłem funkcję MsgBox wyświetlającą okno komunikatu z ostrzeżeniem, by funkcji funDataTygodniowaISO8601
w tej postaci nie stosować do jakichkolwiek obliczeń.






Brak komentarzy:
Prześlij komentarz