Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #35560 > unrolled thread
| Started by | Tassilo Horn <tsdh@gnu.org> |
|---|---|
| First post | 2016-09-07 08:58 +0200 |
| Last post | 2016-09-13 23:39 +0100 |
| Articles | 8 — 3 participants |
Back to article view | Back to comp.lang.java.programmer
Parsing calendar weeks to LocalDates with DateTimeFormatter Tassilo Horn <tsdh@gnu.org> - 2016-09-07 08:58 +0200
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Tassilo Horn <tsdh@gnu.org> - 2016-09-07 10:11 +0200
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> - 2016-09-09 22:46 +0100
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> - 2016-09-11 16:43 +0100
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Lew <lewbloch@gmail.com> - 2016-09-13 17:50 -0700
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> - 2016-09-17 19:34 +0100
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Tassilo Horn <tsdh@gnu.org> - 2016-09-12 09:18 +0200
Re: Parsing calendar weeks to LocalDates with DateTimeFormatter Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> - 2016-09-13 23:39 +0100
| From | Tassilo Horn <tsdh@gnu.org> |
|---|---|
| Date | 2016-09-07 08:58 +0200 |
| Subject | Parsing calendar weeks to LocalDates with DateTimeFormatter |
| Message-ID | <87inu8gpqv.fsf@gnu.org> |
Hi all,
I have a
DateTimeFormatter FORMATTER_KW = DateTimeFormatter.ofPattern("ww.YYYY");
for formatting LocalDates as calendar weeks. That works fine, however I
can't use that to parse calendar week strings to LocalDates, e.g.,
FORMATTER_KW.parse("44.2016", LocalDate::from);
throws
java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor:
{WeekBasedYear[WeekFields[MONDAY,4]]=2016,
WeekOfWeekBasedYear[WeekFields[MONDAY,4]]=50},ISO of type java.time.format.Parsed
at java.time.LocalDate.from(LocalDate.java:368)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 63 more
Sounds like it is complaining that the date is underspecified which it
obviously is. So I'd like such a calendar week to resolve to the last
work day in that week. (The calendar weeks are estimated deliveries.)
After a bit of doc reading and experimenting, I came up with this
solution which seems to work ok but looks a bit complicated for such a
common task such as week-date conversion. So is there anything better?
// When parsing calendar weeks like "22.2016", we want to get the last work day in that week. We
// assume that everyone in every locale has a 5 days work week (don't know how to do better).
return FORMATTER_KW.parse(editorText, temporal ->
{
WeekFields weekFields = WeekFields.of(Locale.getDefault());
DayOfWeek firstDayInWeek = weekFields.getFirstDayOfWeek();
DayOfWeek lastWorkDay = firstDayInWeek.minus(4);
long weekOfWeekBasedYear = temporal.getLong(weekFields.weekOfWeekBasedYear());
long year = temporal.getLong(weekFields.weekBasedYear());
LocalDate date = LocalDate.of(0, 1, 1);
date = date.plusYears(year);
date = date.plusWeeks(weekOfWeekBasedYear);
date = date.with(lastWorkDay);
return date;
});
Bye,
Tassilo
[toc] | [next] | [standalone]
| From | Tassilo Horn <tsdh@gnu.org> |
|---|---|
| Date | 2016-09-07 10:11 +0200 |
| Message-ID | <87eg4wgmcw.fsf@gnu.org> |
| In reply to | #35560 |
Tassilo Horn <tsdh@gnu.org> writes:
> // When parsing calendar weeks like "22.2016", we want to get
> // the last work day in that week. We assume that everyone
> // in every locale has a 5 days work week (don't know how to do
> // better).
> return FORMATTER_KW.parse(editorText, temporal ->
> {
> WeekFields weekFields = WeekFields.of(Locale.getDefault());
> DayOfWeek firstDayInWeek = weekFields.getFirstDayOfWeek();
> DayOfWeek lastWorkDay = firstDayInWeek.minus(4);
> long weekOfWeekBasedYear = temporal.getLong(weekFields.weekOfWeekBasedYear());
> long year = temporal.getLong(weekFields.weekBasedYear());
> LocalDate date = LocalDate.of(0, 1, 1);
> date = date.plusYears(year);
> date = date.plusWeeks(weekOfWeekBasedYear);
> date = date.with(lastWorkDay);
> return date;
> });
Oh, obviously StartOfWeek - 4 days is not a sane assumption for last
workday, and neither would be StartOfWeek + 4. So right now, I just use
DayOfWeek.FRIDAY.
Bye,
Tassilo
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2016-09-09 22:46 +0100 |
| Message-ID | <XSD8BfGz2y0XFwl7@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #35560 |
In comp.lang.java.programmer message <87inu8gpqv.fsf@gnu.org>, Wed, 7
Sep 2016 08:58:48, Tassilo Horn <tsdh@gnu.org> posted:
>Hi all,
>
>I have a
>
> DateTimeFormatter FORMATTER_KW = DateTimeFormatter.ofPattern("ww.YYYY");
>
>for formatting LocalDates as calendar weeks.
Firstly, you need to say, clearly, what your definition of Week
Numbering is.
You seem to be at U.Koblenz, so you should be using ISO 8601 weeks, in
which all weeks are Mon=1 to Sun=7 and Week 01 contains January 4th
(i.e. is the first week which is all or mostly in the Gregorian Year),
so the last week of the year is numbered 52 or 53; there is never a Week
00 or a Week 54.
ISO Week Numbering is used throughout the sensible part of the Gregorian
world, but not much along the Mexico-Canada borderland.
<http://web.archive.org/web/20150723023855/http://www.merlyn.demon.co.uk
/weekinfo.htm> or later, <http://web.archive.org/web/20150711063435/http
://www.merlyn.demon.co.uk/weekcalc.htm> or later, and <http://web.archiv
e.org/web/20150703002408/http://www.merlyn.demon.co.uk/js-date7.htm> or
later, might help readers; but their code is not Java.
--
(c) John Stockton, Surrey, UK. ¬@merlyn.demon.co.uk Turnpike v6.05 MIME.
Merlyn Web Site < > - FAQish topics, acronyms, & links.
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2016-09-11 16:43 +0100 |
| Message-ID | <wByFVjdwuX1XFw5r@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #35583 |
In comp.lang.java.programmer message <week-20160910025343@ram.dialup.fu-
berlin.de>, Sat, 10 Sep 2016 01:56:51, Stefan Ram <ram@zedat.fu-
berlin.de> posted:
>Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> writes:
>>Firstly, you need to say, clearly, what your definition of Week
>>Numbering is.
>
> In VBA, there is
>
>Function DatePart
>( Interval As String,
> Date,
> [FirstDayOfWeek As VbDayOfWeek = vbSunday],
> [FirstWeekOfYear As VbFirstWeekOfYear = vbFirstJan1] )
>
> , with VbDayOfWeek containing
>
>vbUseSystemDayofWeek, vbSunday, vbMonday, vbTuesday, vbWednesday,
>vbThursday, vbFriday, and vbSaturday
>
> and VbFirstweekofyear containing
>
>vbUseSystem, vbFirstJan1, vbFirstFourDays, and vbFirstFullWeek.
>
> So, one can adjust the first day of the week and the rule
> for the first week. Impressive design, but reportedly
>
>VBA.DateTime.DatePart( "ww", #2059-12-30#, vbSunday, vbFirstFourDays )
>
> gives 53, which reportedly is wrong. It reportedly should be 1 instead.
> This reportedly is a bug that reportedly repeats every 28 years.
>
> So, in the end, one still has to program it oneself in VBA
> if one wants a bug-free implementation.
Not _oneself_; it is sufficient for one individual to have done it.
I have done it for VBscript; Java could be different. I see Java has
DateSerial, I suppose equivalent.
See, preferably using a browser which runs VBscript, in
http://web.archive.org/web/20150511204319/http://www.merlyn.demon.co.uk/
vb-date2.htm>.
The 28-year interval only applies between missing leap years; and there
are three errors in every such interval - 3 or 4 per century. Another
error repeats every 400 years; next 2101-01-02.
Microsoft have a bug fix, which that page links to, for the 3/28-year
errors.
For VBscript code written and tested in IE8, see, in the cited page, the
script section beginning with the line
Sub WeekNumJRS(Tdy, YNo, WNo, DoW) '' Tdy is CDate in; Y W D out
Any code giving the ISO 8601 Week Number for a date needs to give also
the year number; and it might as well give also the day-of-week number
(Sunday=7, as earlier established in the Book of Genesis).
If you produce corresponding well-tested similar code in Java, I'd be
pleased to have a URL for it that I may cite. E-address implied by
signature + headers.
--
(c) John Stockton, near London. Mail ?.?.Stockton@physics.org
Web < > - FAQish topics, acronyms, and links.
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2016-09-13 17:50 -0700 |
| Message-ID | <d704e04a-a4ec-4b93-bc18-4a942d0707a6@googlegroups.com> |
| In reply to | #35588 |
Dr J R Stockton wrote: > Any code giving the ISO 8601 Week Number for a date needs to give also > the year number; and it might as well give also the day-of-week number > (Sunday=7, as earlier established in the Book of Genesis). The Book of Genesis did not establish Sunday as day seven. Per the Jewish religion, the Sabbath is Saturday, implying Saturday=7. -- Lew
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2016-09-17 19:34 +0100 |
| Message-ID | <Qp8N$UCCzY3XFw$m@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #35597 |
In comp.lang.java.programmer message <d704e04a-a4ec-4b93-bc18-4a942d0707 a6@googlegroups.com>, Tue, 13 Sep 2016 17:50:14, Lew <lewbloch@gmail.com> posted: >Dr J R Stockton wrote: >> Any code giving the ISO 8601 Week Number for a date needs to give also >> the year number; and it might as well give also the day-of-week number >> (Sunday=7, as earlier established in the Book of Genesis). > >The Book of Genesis did not establish Sunday as day seven. Per the >Jewish religion, the Sabbath is Saturday, implying Saturday=7. ISO weeks by definition use the Gregorian Calendar, authorised by Pope Gregory XIII. The ISO 8601 definition is that ISO Week 1 contains the first Thursday of the Gregorian Calendar Year, which is equivalent to saying that Week 1 is the first ISO Week which lies mostly within the G C Y. Users of non-Gregorian calendars could use an analogous definition. I believe that Anno Mundi Day 2 was (mostly) Julian BC 3761/10/07, a Monday. -- (c) John Stockton, Surrey, UK. ¬@merlyn.demon.co.uk Turnpike v6.05 MIME. Merlyn Web Site < > - FAQish topics, acronyms, & links.
[toc] | [prev] | [next] | [standalone]
| From | Tassilo Horn <tsdh@gnu.org> |
|---|---|
| Date | 2016-09-12 09:18 +0200 |
| Message-ID | <8760q1fuw4.fsf@gnu.org> |
| In reply to | #35583 |
Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> writes:
Hi,
>>I have a
>>
>> DateTimeFormatter FORMATTER_KW = DateTimeFormatter.ofPattern("ww.YYYY");
>>
>>for formatting LocalDates as calendar weeks.
>
>
> Firstly, you need to say, clearly, what your definition of Week
> Numbering is.
>
> You seem to be at U.Koblenz,
Not anymore but...
> so you should be using ISO 8601 weeks, in which all weeks are Mon=1 to
> Sun=7 and Week 01 contains January 4th (i.e. is the first week which
> is all or mostly in the Gregorian Year), so the last week of the year
> is numbered 52 or 53; there is never a Week 00 or a Week 54.
...that's the week numbering definition we are using, yes.
> ISO Week Numbering is used throughout the sensible part of the
> Gregorian world, but not much along the Mexico-Canada borderland.
As far as I can tell, we don't have a customer in the Mexico-Canada
borderland yet.
> <http://web.archive.org/web/20150723023855/http://www.merlyn.demon.co.uk
> /weekinfo.htm> or later, <http://web.archive.org/web/20150711063435/http
> ://www.merlyn.demon.co.uk/weekcalc.htm> or later, and <http://web.archiv
> e.org/web/20150703002408/http://www.merlyn.demon.co.uk/js-date7.htm> or
> later, might help readers; but their code is not Java.
No problem in not being Java, and it's definitely nice how to do these
calculations "by hand". Yet my question was if there was some standard
way to come from a calendar week (ISO 8601) to a LocalDate other than
the snippet I've posted.
Bye,
Tassilo
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1600@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2016-09-13 23:39 +0100 |
| Message-ID | <AHzpEb45AI2XFwXw@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #35589 |
In comp.lang.java.programmer message <8760q1fuw4.fsf@gnu.org>, Mon, 12
Sep 2016 09:18:51, Tassilo Horn <tsdh@gnu.org> posted:
>No problem in not being Java, and it's definitely nice how to do these
>calculations "by hand". Yet my question was if there was some standard
>way to come from a calendar week (ISO 8601) to a LocalDate other than
>the snippet I've posted.
Well, clearly one cannot properly convert a Week to a Day!
This VBscript should be easy, I guess, to convert to Java, and writes
"2016-09-13" which is correct.
function YearMonthDay(YWD) '' ISO 8601
dim Y, M, D, FiM, SoY
Y = Left(YWD, 4) : W = Mid(YWD, 7, 2) : D = Right(YWD, 1)
SoY = DateSerial(Y, 1, 1)
FiM = SoY + 3 - (SoY+1) mod 7
YearMonthDay = FiM + 7*(W-1) + D-1
end function
document.write(YearMonthDay("2016-W37-2"))
The function is well-tested, and in the page I cited.
SoY stands for Start of (Gregorian) Year, and I think FiM stands for
First Monday. FiM will be in the range SoY-3 to SoY+3. Adjustment will
probably be needed if the zero dates of VBS & Java are not the same day
of the week.
YearMonthDay returns a VBS CDate, which I suppose to be similar to a
Java LocalDate.
Note : in VBS, there is a standard, Microsoft-documented way using
DatePart to get an ISO 8601 week number from a Date (and there might be
an inverse documented). There is a minor problem, IIRC, that it does
not return the year number; and a major one that it gives an incorrect
result for three days per 28 years. If they do have an inverse, I would
not trust it until verified for at least every day in 400 years.
--
(c) John Stockton, Surrey, UK. ¬@merlyn.demon.co.uk Turnpike v6.05 MIME.
Merlyn Web Site < > - FAQish topics, acronyms, & links.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web