aboutsummaryrefslogtreecommitdiffstats
path: root/date.c
AgeCommit message (Collapse)AuthorFilesLines
2024-04-05date: make DATE_MODE thread-safeRené Scharfe1-18/+18
date_mode_from_type() modifies a static variable and returns a pointer to it. This is not thread-safe. Most callers of date_mode_from_type() use it via the macro DATE_MODE and pass its result on to functions like show_date(), which take a const pointer and don't modify the struct. Avoid the static storage by putting the variable on the stack and returning the whole struct date_mode. Change functions that take a constant pointer to expect the whole struct instead. Reduce the cost of passing struct date_mode around on 64-bit systems by reordering its members to close the hole between the 32-bit wide .type and the 64-bit aligned .strftime_fmt as well as the alignment hole at the end. sizeof reports 24 before and 16 with this change on x64. Keep .type at the top to still allow initialization without designator -- though that's only done in a single location, in builtin/blame.c. Signed-off-by: René Scharfe <l.s.r@web.de> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-13date: make "iso-strict" conforming for the UTC timezoneBeat Bolli1-5/+9
ISO 8601-1:2020-12 specifies that a zero timezone offset must be denoted with a "Z" suffix instead of the numeric "+00:00". Add the correponding special case to show_date() and a new test. Changing an established output format which might be depended on by scripts is always problematic, but here we choose to adhere more closely to the published standard. Reported-by: Michael Osipov <michael.osipov@innomotics.com> Signed-off-by: Beat Bolli <dev+git@drbeat.li> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-09Merge branch 'en/header-split-cache-h-part-2'Junio C Hamano1-1/+2
More header clean-up. * en/header-split-cache-h-part-2: (22 commits) reftable: ensure git-compat-util.h is the first (indirect) include diff.h: reduce unnecessary includes object-store.h: reduce unnecessary includes commit.h: reduce unnecessary includes fsmonitor: reduce includes of cache.h cache.h: remove unnecessary headers treewide: remove cache.h inclusion due to previous changes cache,tree: move basic name compare functions from read-cache to tree cache,tree: move cmp_cache_name_compare from tree.[ch] to read-cache.c hash-ll.h: split out of hash.h to remove dependency on repository.h tree-diff.c: move S_DIFFTREE_IFXMIN_NEQ define from cache.h dir.h: move DTYPE defines from cache.h versioncmp.h: move declarations for versioncmp.c functions from cache.h ws.h: move declarations for ws.c functions from cache.h match-trees.h: move declarations for match-trees.c functions from cache.h pkt-line.h: move declarations for pkt-line.c functions from cache.h base85.h: move declarations for base85.c functions from cache.h copy.h: move declarations for copy.c functions from cache.h server-info.h: move declarations for server-info.c functions from cache.h packfile.h: move pack_window and pack_entry from cache.h ...
2023-04-25Merge branch 'en/header-split-cache-h'Junio C Hamano1-0/+1
Header clean-up. * en/header-split-cache-h: (24 commits) protocol.h: move definition of DEFAULT_GIT_PORT from cache.h mailmap, quote: move declarations of global vars to correct unit treewide: reduce includes of cache.h in other headers treewide: remove double forward declaration of read_in_full cache.h: remove unnecessary includes treewide: remove cache.h inclusion due to pager.h changes pager.h: move declarations for pager.c functions from cache.h treewide: remove cache.h inclusion due to editor.h changes editor: move editor-related functions and declarations into common file treewide: remove cache.h inclusion due to object.h changes object.h: move some inline functions and defines from cache.h treewide: remove cache.h inclusion due to object-file.h changes object-file.h: move declarations for object-file.c functions from cache.h treewide: remove cache.h inclusion due to git-zlib changes git-zlib: move declarations for git-zlib functions from cache.h treewide: remove cache.h inclusion due to object-name.h changes object-name.h: move declarations for object-name.c functions from cache.h treewide: remove unnecessary cache.h inclusion treewide: be explicit about dependence on mem-pool.h treewide: be explicit about dependence on oid-array.h ...
2023-04-24treewide: remove cache.h inclusion due to previous changesElijah Newren1-1/+1
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-24treewide: be explicit about dependence on strbuf.hElijah Newren1-0/+1
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-20Merge branch 'rs/remove-approxidate-relative'Junio C Hamano1-14/+0
The approxidate() API has been simplified by losing an extra function that did the same thing as another one. * rs/remove-approxidate-relative: date: remove approxidate_relative()
2023-04-11pager.h: move declarations for pager.c functions from cache.hElijah Newren1-0/+1
Signed-off-by: Elijah Newren <newren@gmail.com> Acked-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-04-10date: remove approxidate_relative()René Scharfe1-14/+0
When 29f4332e66 (Quit passing 'now' to date code, 2019-09-11) removed its timeval parameter, approxidate_relative() became equivalent to approxidate(). Convert its last two call sites and remove the redundant function. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-21treewide: be explicit about dependence on gettext.hElijah Newren1-0/+1
Dozens of files made use of gettext functions, without explicitly including gettext.h. This made it more difficult to find which files could remove a dependence on cache.h. Make C files explicitly include gettext.h if they are using it. However, while compat/fsmonitor/fsm-ipc-darwin.c should also gain an include of gettext.h, it was left out to avoid conflicting with an in-flight topic. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-01-13date.c: allow ISO 8601 reduced precision timesĐoàn Trần Công Danh1-0/+37
ISO 8601 permits "reduced precision" time representations to omit the seconds value or both the minutes and the seconds values. The abbreviate times could look like 17:45 or 1745 to omit the seconds, or simply as 17 to omit both the minutes and the seconds. parse_date_basic accepts the 17:45 format but it rejects the other two. Change it to accept 4-digit and 2-digit time values when they follow a recognized date and a 'T'. Before this change: $ TZ=UTC test-tool date approxidate 2022-12-13T23:00 2022-12-13T2300 2022-12-13T23 2022-12-13T23:00 -> 2022-12-13 23:00:00 +0000 2022-12-13T2300 -> 2022-12-13 23:54:13 +0000 2022-12-13T23 -> 2022-12-13 23:54:13 +0000 After this change: $ TZ=UTC helper/test-tool date approxidate 2022-12-13T23:00 2022-12-13T2300 2022-12-13T23 2022-12-13T23:00 -> 2022-12-13 23:00:00 +0000 2022-12-13T2300 -> 2022-12-13 23:00:00 +0000 2022-12-13T23 -> 2022-12-13 23:00:00 +0000 Note: ISO 8601 also allows reduced precision date strings such as "2022-12" and "2022". This patch does not attempt to address these. Reported-by: Pat LaVarre <plavarre@purestorage.com> Signed-off-by: Phil Hord <phil.hord@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-10-17date: mark unused parameters in handler functionsJeff King1-3/+3
When parsing approxidates, we use a table to map special strings (like "noon") to functions which handle them. Not all functions need the "now" parameter, as they are not relative (e.g., "yesterday" does, but "pm" does not). Let's annotate those to make -Wunused-parameter happy. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-16date API: add and use a date_mode_release()Ævar Arnfjörð Bjarmason1-0/+5
Fix a memory leak in the parse_date_format() function by providing a new date_mode_release() companion function. By using this in "t/helper/test-date.c" we can mark the "t0006-date.sh" test as passing when git is compiled with SANITIZE=leak, and whitelist it to run under "GIT_TEST_PASSING_SANITIZE_LEAK=true" by adding "TEST_PASSES_SANITIZE_LEAK=true" to the test itself. The other tests that expose this memory leak (i.e. take the "mode->type == DATE_STRFTIME" branch in parse_date_format()) are "t6300-for-each-ref.sh" and "t7004-tag.sh". The former is due to an easily fixed leak in "ref-filter.c", and brings the failures in "t6300-for-each-ref.sh" down from 51 to 48. Fixing the remaining leaks will have to wait until there's a release_revisions() in "revision.c", as they have to do with leaks via "struct rev_info". There is also a leak in "builtin/blame.c" due to its call to parse_date_format() to parse the "blame.date" configuration. However as it declares a file-level "static struct date_mode blame_date_mode" to track the data, LSAN will not report it as a leak. It's possible to get valgrind(1) to complain about it with e.g.: valgrind --leak-check=full --show-leak-kinds=all ./git -P -c blame.date=format:%Y blame README.md But let's focus on things LSAN complains about, and are thus observable with "TEST_PASSES_SANITIZE_LEAK=true". We should get to fixing memory leaks in "builtin/blame.c", but as doing so would require some re-arrangement of cmd_blame() let's leave it for some other time. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-16date API: provide and use a DATE_MODE_INITÆvar Arnfjörð Bjarmason1-2/+1
Provide and use a DATE_MODE_INIT macro. Most of the users of struct date_mode" use it via pretty.h's "struct pretty_print_context" which doesn't have an initialization macro, so we're still bound to being initialized to "{ 0 }" by default. But we can change the couple of callers that directly declared a variable on the stack to instead use the initializer, and thus do away with the "mode.local = 0" added in add00ba2de9 (date: make "local" orthogonal to date format, 2015-09-03). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-16date API: create a date.h, split from cache.hÆvar Arnfjörð Bjarmason1-0/+1
Move the declaration of the date.c functions from cache.h, and adjust the relevant users to include the new date.h header. The show_ident_date() function belonged in pretty.h (it's defined in pretty.c), its two users outside of pretty.c didn't strictly need to include pretty.h, as they get it indirectly, but let's add it to them anyway. Similarly, the change to "builtin/{fast-import,show-branch,tag}.c" isn't needed as far as the compiler is concerned, but since they all use the "DATE_MODE()" macro we now define in date.h, let's have them include it. We could simply include this new header in "cache.h", but as this change shows these functions weren't common enough to warrant including in it in the first place. By moving them out of cache.h changes to this API will no longer cause a (mostly) full re-build of the project when "make" is run. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-11-04strbuf_addftime(): handle "%s" manuallyJeff King1-1/+1
The strftime() function has a non-standard "%s" extension, which prints the number of seconds since the epoch. But the "struct tm" we get has already been adjusted for a particular time zone; going back to an epoch time requires knowing that zone offset. Since strftime() doesn't take such an argument, round-tripping to a "struct tm" and back to the "%s" format may produce the wrong value (off by tz_offset seconds). Since we're already passing in the zone offset courtesy of c3fbf81a85 (strbuf: let strbuf_addftime handle %z and %Z itself, 2017-06-15), we can use that same value to adjust our epoch seconds accordingly. Note that the description above makes it sound like strftime()'s "%s" is useless (and really, the issue is shared by mktime(), which is what strftime() would use under the hood). But it gets the two cases for which it's designed correct: - the result of gmtime() will have a zero offset, so no adjustment is necessary - the result of localtime() will be offset by the local zone offset, and mktime() and strftime() are defined to assume this offset when converting back (there's actually some magic here; some implementations record this in the "struct tm", but we can't portably access or manipulate it. But they somehow "know" whether a "struct tm" is from gmtime() or localtime()). This latter point means that "format-local:%s" actually works correctly already, because in that case we rely on the system routines due to 6eced3ec5e (date: use localtime() for "-local" time formats, 2017-06-15). Our problem comes when trying to show times in the author's zone, as the system routines provide no mechanism for converting in non-local zones. So in those cases we have a "struct tm" that came from gmtime(), but has been manipulated according to our offset. The tests cover the broken round-trip by formatting "%s" for a time in a non-system timezone. We use the made-up "+1234" here, which has two advantages. One, we know it won't ever be the real system zone (and so we're actually testing a case that would break). And two, since it has a minute component, we're testing the full decoding of the +HHMM zone into a number of seconds. Likewise, we test the "-1234" variant to make sure there aren't any sign mistakes. There's one final test, which covers "format-local:%s". As noted, this already passes, but it's important to check that we didn't regress this case. In particular, the caller in show_date() is relying on localtime() to have done the zone adjustment, independent of any tz_offset we compute ourselves. These should match up, since our local_tzoffset() is likewise built around localtime(). But it would be easy for a caller to forget to pass in a correct tz_offset to strbuf_addftime(). Fortunately show_date() does this correctly (it has to because of the existing handling of %z), and the test continues to pass. So this one is just future-proofing against a change in our assumptions. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-06-16comments: avoid using the gender of our usersFelipe Contreras1-1/+1
We generally avoid specifying the gender of our users in order to be more inclusive, but sometimes a few slip by due to habit. Since by doing a little bit of rewording we can avoid this irrelevant detail, let's do so. Inspired-by: Derrick Stolee <dstolee@microsoft.com> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-24date.c: allow compact version of ISO-8601 datetimeĐoàn Trần Công Danh1-0/+14
Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-24date.c: skip fractional second part of ISO-8601Đoàn Trần Công Danh1-0/+12
git-commit(1) says ISO-8601 is one of our supported date format. ISO-8601 allows timestamps to have a fractional number of seconds. We represent time only in terms of whole seconds, so we never bothered parsing fractional seconds. However, it's better for us to parse and throw away the fractional part than to refuse to parse the timestamp at all. And refusing parsing fractional second part may confuse the parse to think fractional and timezone as day and month in this example: 2008-02-14 20:30:45.019-04:00 While doing this, make sure that we only interpret the number after the second and the dot as fractional when and only when the date is known, since only ISO-8601 allows the fractional part, and we've taught our users to interpret "12:34:56.7.days.ago" as a way to specify a time relative to current time. Reported-by: Brian M. Carlson <sandals@crustytoothpaste.net> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-24date.c: validate and set time in a helper functionĐoàn Trần Công Danh1-4/+15
In a later patch, we will reuse this logic, move it to a helper, now. While we're at it, explicit states that we intentionally ignore old-and-defective 2nd leap second. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-23date.c: s/is_date/set_date/Đoàn Trần Công Danh1-11/+11
The function is_date, confusingly also set tm_year. tm_mon, and tm_mday after validating input. Rename to set_date to reflect its real usage. Also, change return value is 0 on success and -1 on failure following our convention on function do some real work. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-11-30date.c: switch to reentrant {gm,local}time_rDoan Tran Cong Danh1-8/+10
Originally, git was intended to be single-thread executable. `gmtime(3)' and `localtime(3)' can be used in such codebase for cleaner code. Overtime, we're employing multithread in our code base. Let's phase out `gmtime(3)' and `localtime(3)' in favour of `gmtime_r(3)' and `localtime_r(3)'. Signed-off-by: Doan Tran Cong Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-12Quit passing 'now' to date codeStephen P. Smith1-14/+13
Commit b841d4ff43 (Add `human` format to test-tool, 2019-01-28) added a get_time() function which allows $GIT_TEST_DATE_NOW in the environment to override the current time. So we no longer need to interpret that variable in cmd__date(). Therefore, we can stop passing the "now" parameter down through the date functions, since nobody uses them. Note that we do need to make sure all of the previous callers that took a "now" parameter are correctly using get_time(). Signed-off-by: Stephen P. Smith <ischis2@cox.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-20completion: add more parameter value completionNguyễn Thái Ngọc Duy1-0/+4
This adds value completion for a couple more paramters. To make it easier to maintain these hard coded lists, add a comment at the original list/code to remind people to update git-completion.bash too. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-06Merge branch 'lt/date-human'Junio C Hamano1-22/+126
A new date format "--date=human" that morphs its output depending on how far the time is from the current time has been introduced. "--date=auto" can be used to use this new format when the output is going to the pager or to the terminal and otherwise the default format. * lt/date-human: Add `human` date format tests. Add `human` format to test-tool Add 'human' date format documentation Replace the proposed 'auto' mode with 'auto:' Add 'human' date format
2019-01-29Add `human` format to test-toolStephen P. Smith1-4/+17
Add the human format support to the test tool so that GIT_TEST_DATE_NOW can be used to specify the current time. The get_time() helper function was created and and checks the GIT_TEST_DATE_NOW environment variable. If GIT_TEST_DATE_NOW is set, then that date is used instead of the date returned by by gettimeofday(). All calls to gettimeofday() were replaced by calls to get_time(). Renamed occurances of TEST_DATE_NOW to GIT_TEST_DATE_NOW since the variable is now used in the get binary and not just in the test-tool. Signed-off-by: Stephen P. Smith <ischis2@cox.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-24show_date_relative(): drop unused "tz" parameterJeff King1-4/+4
The timestamp we receive is in epoch time, so there's no need for a timezone parameter to interpret it. The matching show_date() uses "tz" to show dates in author local time, but relative dates show only the absolute time difference. The author's location is irrelevant, barring relativistic effects from using Git close to the speed of light. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-22Replace the proposed 'auto' mode with 'auto:'Stephen P. Smith1-7/+8
In addition to adding the 'human' format, the patch added the auto keyword which could be used in the config file as an alternate way to specify the human format. Removing 'auto' cleans up the 'human' format interface. Added the ability to specify mode 'foo' if the pager is being used by using auto:foo syntax. Therefore, 'auto:human' date mode defaults to human if we're using the pager. So you can do git config --add log.date auto:human and your "git log" commands will show the human-legible format unless you're scripting things. Signed-off-by: Stephen P. Smith <ischis2@cox.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-18Add 'human' date formatLinus Torvalds1-20/+110
This adds --date=human, which skips the timezone if it matches the current time-zone, and doesn't print the whole date if that matches (ie skip printing year for dates that are "this year", but also skip the whole date itself if it's in the last few days and we can just say what weekday it was). For really recent dates (same day), use the relative date stamp, while for old dates (year doesn't match), don't bother with time and timezone. Also add 'auto' date mode, which defaults to human if we're using the pager. So you can do git config --add log.date auto and your "git log" commands will show the human-legible format unless you're scripting things. Note that this time format still shows the timezone for recent enough events (but not so recent that they show up as relative dates). You can combine it with the "-local" suffix to never show timezones for an even more simplified view. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Stephen P. Smith <ischis2@cox.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-07approxidate: fix NULL dereference in date_time()Jeff King1-1/+1
When we see a time like "noon", we pass "12" to our date_time() helper, which sets the hour to 12pm. If the current time is before noon, then we wrap around to yesterday using date_yesterday(). But unlike the normal calls to date_yesterday() from approxidate_alpha(), we pass a NULL "num" parameter. Since c27cc94fad (approxidate: handle pending number for "specials", 2018-11-02), that causes a segfault. One way to fix this is by checking for NULL. But arguably date_time() is abusing our helper by passing NULL in the first place (and this is the only case where one of these "special" parsers is used this way). So instead, let's have it just do the 1-day subtraction itself. It's still just a one-liner due to our update_tm() helper. Note that the test added here is a little funny, as we say "10am noon", which makes the "10am" seem pointless. But this bug can only be triggered when it the currently-parsed hour is before the special time. The latest special time is "tea" at 1700, but t0006 uses a hard-coded TEST_DATE_NOW of 1900. We could reset TEST_DATE_NOW, but that may lead to confusion in other tests. Just saying "10am noon" makes this test self-contained. Reported-by: Carlo Arenas <carenas@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-02approxidate: handle pending number for "specials"Jeff King1-27/+33
The approxidate parser has a table of special keywords like "yesterday", "noon", "pm", etc. Some of these, like "pm", do the right thing if we've recently seen a number: "3pm" is what you'd think. However, most of them do not look at or modify the pending-number flag at all, which means a number may "jump" across a significant keyword and be used unexpectedly. For example, when parsing: January 5th noon pm we'd connect the "5" to "pm", and ignore it as a day-of-month. This is obviously a bit silly, as "noon" already implies "pm". And other mis-parsed things are generally as silly ("January 5th noon, years ago" would connect the 5 to "years", but probably nobody would type that). However, the fix is simple: when we see a keyword like "noon", we should flush the pending number (as we would if we hit another number, or the end of the string). In a few of the specials that actually modify the day, we can simply throw away the number (saying "Jan 5 yesterday" should not respect the number at all). Note that we have to either move or forward-declare the static pending_number() to make it accessible to these functions; this patch moves it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-06Replace all die("BUG: ...") calls by BUG() onesJohannes Schindelin1-1/+1
In d8193743e08 (usage.c: add BUG() function, 2017-05-12), a new macro was introduced to use for reporting bugs instead of die(). It was then subsequently used to convert one single caller in 588a538ae55 (setup_git_env: convert die("BUG") to BUG(), 2017-05-12). The cover letter of the patch series containing this patch (cf 20170513032414.mfrwabt4hovujde2@sigill.intra.peff.net) is not terribly clear why only one call site was converted, or what the plan is for other, similar calls to die() to report bugs. Let's just convert all remaining ones in one fell swoop. This trick was performed by this invocation: sed -i 's/die("BUG: /BUG("/g' $(git grep -l 'die("BUG' \*.c) Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-06Merge branch 'ab/strbuf-addftime-tzname-boolify'Junio C Hamano1-1/+1
strbuf_addftime() is further getting tweaked. * ab/strbuf-addftime-tzname-boolify: strbuf: change an always NULL/"" strbuf_addftime() param to bool strbuf.h comment: discuss strbuf_addftime() arguments in order
2017-07-01strbuf: change an always NULL/"" strbuf_addftime() param to boolÆvar Arnfjörð Bjarmason1-1/+1
strbuf_addftime() allows callers to pass a time zone name for expanding %Z. The only current caller either passes the empty string or NULL, in which case %Z is handed over verbatim to strftime(3). Replace that string parameter with a flag controlling whether to remove %Z from the format specification. This simplifies the code. Commit-message-by: René Scharfe <l.s.r@web.de> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-22Merge branch 'rs/strbuf-addftime-zZ'Junio C Hamano1-2/+12
As there is no portable way to pass timezone information to strftime, some output format from "git log" and friends are impossible to produce. Teach our own strbuf_addftime to replace %z and %Z with caller-supplied values to help working around this. * rs/strbuf-addftime-zZ: date: use localtime() for "-local" time formats t0006: check --date=format zone offsets strbuf: let strbuf_addftime handle %z and %Z itself
2017-06-15date: use localtime() for "-local" time formatsJeff King1-2/+12
When we convert seconds-since-epochs timestamps into a broken-down "struct tm", we do so by adjusting the timestamp according to the known offset and then using gmtime() to break down the result. This means that the resulting struct "knows" that it's in GMT, even though the time it represents is adjusted for a different zone. The fields where it stores this data are not portably accessible, so we have no way to override them to tell them the real zone info. For the most part, this works. Our date-formatting routines don't pay attention to these inaccessible fields, and use the same tz info we provided for adjustment. The one exception is when we call strftime(), whose %Z format reveals this hidden timezone data. We solved that by always showing the empty string for %Z. This is allowed by POSIX, but not very helpful to the user. We can't make this work in the general case, as there's no portable function for setting an arbitrary timezone (and anyway, we don't have the zone name for the author zones, only their offsets). But for the special case of the "-local" formats, we can just skip the adjustment and use localtime() instead of gmtime(). This makes --date=format-local:%Z work correctly, showing the local timezone instead of an empty string. The new test checks the result for "UTC", our default test-lib value for $TZ. Using something like EST5 might be more interesting, but the actual zone string is system-dependent (for instance, on my system it expands to just EST). Hopefully "UTC" is vanilla enough that every system treats it the same. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-15strbuf: let strbuf_addftime handle %z and %Z itselfRené Scharfe1-1/+1
There is no portable way to pass timezone information to strftime. Add parameters for timezone offset and name to strbuf_addftime and let it handle the timezone-related format specifiers %z and %Z internally. Callers can opt out for %Z by passing NULL as timezone name. %z is always handled internally -- this helps on Windows, where strftime would expand it to a timezone name (same as %Z), in violation of POSIX. Modifiers are not handled, e.g. %Ez is still passed to strftime. Use an empty string as timezone name in show_date (the only current caller) for now because we only have the timezone offset in non-local mode. POSIX allows %Z to resolve to an empty string in case of missing information. Helped-by: Ulrich Mueller <ulm@gentoo.org> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-27date.c: abort if the system time cannot handle one of our timestampsJohannes Schindelin1-2/+15
We are about to switch to a new data type for time stamps that is definitely not smaller or equal, but larger or equal to time_t. So before using the system functions to process or format timestamps, let's make extra certain that they can handle what we feed them. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-27timestamp_t: a new data type for timestampsJohannes Schindelin1-33/+33
Git's source code assumes that unsigned long is at least as precise as time_t. Which is incorrect, and causes a lot of problems, in particular where unsigned long is only 32-bit (notably on Windows, even in 64-bit versions). So let's just use a more appropriate data type instead. In preparation for this, we introduce the new `timestamp_t` data type. By necessity, this is a very, very large patch, as it has to replace all timestamps' data type in one go. As we will use a data type that is not necessarily identical to `time_t`, we need to be very careful to use `time_t` whenever we interact with the system functions, and `timestamp_t` everywhere else. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-23PRItime: introduce a new "printf format" for timestampsJohannes Schindelin1-13/+13
Currently, Git's source code treats all timestamps as if they were unsigned longs. Therefore, it is okay to write "%lu" when printing them. There is a substantial problem with that, though: at least on Windows, time_t is *larger* than unsigned long, and hence we will want to switch away from the ill-specified `unsigned long` data type. So let's introduce the pseudo format "PRItime" (currently simply being defined to "lu") to make it easier to change the data type used for timestamps. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-23parse_timestamp(): specify explicitly where we parse timestampsJohannes Schindelin1-3/+3
Currently, Git's source code represents all timestamps as `unsigned long`. In preparation for using a more appropriate data type, let's introduce a symbol `parse_timestamp` (currently being defined to `strtoul`) where appropriate, so that we can later easily switch to, say, use `strtoull()` instead. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-27date: add "unix" formatJeff King1-0/+8
We already have "--date=raw", which is a Unix epoch timestamp plus a contextual timezone (either the author's or the local). But one may not care about the timezone and just want the epoch timestamp by itself. It's not hard to parse the two apart, but if you are using a pretty-print format, you may want git to show the "finished" form that the user will see. We can accomodate this by adding a new date format, "unix", which is basically "raw" without the timezone. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-20local_tzoffset: detect errors from tm_to_time_tJeff King1-0/+2
When we want to know the local timezone offset at a given timestamp, we compute it by asking for localtime() at the given time, and comparing the offset to GMT at that time. However, there's some juggling between time_t and "struct tm" which happens, which involves calling our own tm_to_time_t(). If that function returns an error (e.g., because it only handles dates up to the year 2099), it returns "-1", which we treat as a time_t, and is clearly bogus, leading to bizarre timestamps (that seem to always adjust the time back to (time_t)(uint32_t)-1, in the year 2106). It's not a good idea for local_tzoffset() to simply die here; it would make it hard to run "git log" on a repository with funny timestamps. Instead, let's just treat such cases as "zero offset". Reported-by: Norbert Kiesel <nkiesel@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-03date: make "local" orthogonal to date formatJeff King1-25/+45
Most of our "--date" modes are about the format of the date: which items we show and in what order. But "--date=local" is a bit of an oddball. It means "show the date in the normal format, but using the local timezone". The timezone we use is orthogonal to the actual format, and there is no reason we could not have "localized iso8601", etc. This patch adds a "local" boolean field to "struct date_mode", and drops the DATE_LOCAL element from the date_mode_type enum (it's now just DATE_NORMAL plus local=1). The new feature is accessible to users by adding "-local" to any date mode (e.g., "iso-local"), and we retain "local" as an alias for "default-local" for backwards compatibility. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: John Keeping <john@keeping.me.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-03date: check for "local" before anything elseJohn Keeping1-3/+3
In a following commit we will make "local" orthogonal to the format. Although this will not apply to "relative", which does not use the timezone, it applies to all other formats so move the timezone conversion to the start of the function. Signed-off-by: John Keeping <john@keeping.me.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-29introduce "format" date-modeJeff King1-1/+8
This feeds the format directly to strftime. Besides being a little more flexible, the main advantage is that your system strftime may know more about your locale's preferred format (e.g., how to spell the days of the week). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-29convert "enum date_mode" into a structJeff King1-18/+25
In preparation for adding date modes that may carry extra information beyond the mode itself, this patch converts the date_mode enum into a struct. Most of the conversion is fairly straightforward; we pass the struct as a pointer and dereference the type field where necessary. Locations that declare a date_mode can use a "{}" constructor. However, the tricky case is where we use the enum labels as constants, like: show_date(t, tz, DATE_NORMAL); Ideally we could say: show_date(t, tz, &{ DATE_NORMAL }); but of course C does not allow that. Likewise, we cannot cast the constant to a struct, because we need to pass an actual address. Our options are basically: 1. Manually add a "struct date_mode d = { DATE_NORMAL }" definition to each caller, and pass "&d". This makes the callers uglier, because they sometimes do not even have their own scope (e.g., they are inside a switch statement). 2. Provide a pre-made global "date_normal" struct that can be passed by address. We'd also need "date_rfc2822", "date_iso8601", and so forth. But at least the ugliness is defined in one place. 3. Provide a wrapper that generates the correct struct on the fly. The big downside is that we end up pointing to a single global, which makes our wrapper non-reentrant. But show_date is already not reentrant, so it does not matter. This patch implements 3, along with a minor macro to keep the size of the callers sane. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-05Merge branch 'jc/epochtime-wo-tz'Junio C Hamano1-5/+9
"git commit --date=now" or anything that relies on approxidate lost the daylight-saving-time offset. * jc/epochtime-wo-tz: parse_date_basic(): let the system handle DST conversion parse_date_basic(): return early when given a bogus timestamp
2015-04-15parse_date_basic(): let the system handle DST conversionJunio C Hamano1-2/+6
The function parses the input to compute the broken-down time in "struct tm", and the GMT timezone offset. If the timezone offset does not exist in the input, the broken-down time is turned into the number of seconds since epoch both in the current timezone and in GMT and the offset is computed as their difference. However, we forgot to make sure tm.tm_isdst is set to -1 (i.e. let the system figure out if DST is in effect in the current timezone when turning the broken-down time to the number of seconds since epoch); it is done so at the beginning of the function, but a call to match_digit() in the function can lead to a call to gmtime_r() to clobber the field. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Diagnosed-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-04-15parse_date_basic(): return early when given a bogus timestampJunio C Hamano1-3/+3
When the input does not have GMT timezone offset, the code computes it by computing the local and GMT time for the given timestamp. But there is no point doing so if the given timestamp is known to be a bogus one. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-07Merge branch 'jk/approxidate-avoid-y-d-m-over-future-dates'Junio C Hamano1-9/+12
Traditionally we tried to avoid interpreting date strings given by the user as future dates, e.g. GIT_COMMITTER_DATE=2014-12-10 when used early November 2014 was taken as "October 12, 2014" because it is likely that a date in the future, December 10, is a mistake. Loosen this and do not tiebreak by future-ness of the date when (1) ISO-like format is used, and (2) the string can make sense interpreted as both y-m-d and y-d-m. * jk/approxidate-avoid-y-d-m-over-future-dates: approxidate: allow ISO-like dates far in the future pass TIME_DATE_NOW to approxidate future-check
2014-11-13approxidate: allow ISO-like dates far in the futureJeff King1-2/+2
When we are parsing approxidate strings and we find three numbers separate by one of ":/-.", we guess that it may be a date. We feed the numbers to match_multi_number, which checks whether it makes sense as a date in various orderings (e.g., dd/mm/yy or mm/dd/yy, etc). One of the checks we do is to see whether it is a date more than 10 days in the future. This was added in 38035cf (date parsing: be friendlier to our European friends., 2006-04-05), and lets us guess that if it is currently April 2014, then "10/03/2014" is probably March 10th, not October 3rd. This has a downside, though; if you want to be overly generous with your "--until" date specification, we may wrongly parse "2014-12-01" as "2014-01-12" (because the latter is an in-the-past date). If the year is a future year (i.e., both are future dates), it gets even weirder. Due to the vagaries of approxidate, months _after_ the current date (no matter the year) get flipped, but ones before do not. This patch drops the "in the future" check for dates of this form, letting us treat them always as yyyy-mm-dd, even if they are in the future. This does not affect the normal dd/mm/yyyy versus mm/dd/yyyy lookup, because this code path only kicks in when the first number is greater than 70 (i.e., it must be a year, and cannot be either a date or a month). The one possible casualty is that "yyyy-dd-mm" is less likely to be chosen over "yyyy-mm-dd". That's probably OK, though because: 1. The difference happens only when the date is in the future. Already we prefer yyyy-mm-dd for dates in the past. 2. It's unclear whether anybody even uses yyyy-dd-mm regularly. It does not appear in lists of common date formats in Wikipedia[1,2]. 3. Even if (2) is wrong, it is better to prefer ISO-like dates, as that is consistent with what we use elsewhere in git. [1] http://en.wikipedia.org/wiki/Date_and_time_representation_by_country [2] http://en.wikipedia.org/wiki/Calendar_date Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-13pass TIME_DATE_NOW to approxidate future-checkJeff King1-7/+10
The approxidate functions accept an extra "now" parameter to avoid calling time() themselves. We use this in our test suite to make sure we have a consistent time for computing relative dates. However, deep in the bowels of approxidate, we also call time() to check whether possible dates are far in the future. Let's make sure that the "now" override makes it to that spot, too, so we can consistently test that feature. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-09-19Merge branch 'jk/commit-author-parsing'Junio C Hamano1-6/+7
Code clean-up. * jk/commit-author-parsing: determine_author_info(): copy getenv output determine_author_info(): reuse parsing functions date: use strbufs in date-formatting functions record_author_date(): use find_commit_header() record_author_date(): fix memory leak on malformed commit commit: provide a function to find a header in a buffer
2014-08-29pretty: provide a strict ISO 8601 date formatBeat Bolli1-1/+13
Git's "ISO" date format does not really conform to the ISO 8601 standard due to small differences, and it cannot be parsed by ISO 8601-only parsers, e.g. those of XML toolchains. The output from "--date=iso" deviates from ISO 8601 in these ways: - a space instead of the `T` date/time delimiter - a space between time and time zone - no colon between hours and minutes of the time zone Add a strict ISO 8601 date format for displaying committer and author dates. Use the '%aI' and '%cI' format specifiers and add '--date=iso-strict' or '--date=iso8601-strict' date format names. See http://thread.gmane.org/gmane.comp.version-control.git/255879 and http://thread.gmane.org/gmane.comp.version-control.git/52414/focus=52585 for discussion. Signed-off-by: Beat Bolli <bbolli@ewanet.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-27date: use strbufs in date-formatting functionsJeff King1-6/+7
Many of the date functions write into fixed-size buffers. This is a minor pain, as we have to take special precautions, and frequently end up copying the result into a strbuf or heap-allocated buffer anyway (for which we sometimes use strcpy!). Let's instead teach parse_date, datestamp, etc to write to a strbuf. The obvious downside is that we might need to perform a heap allocation where we otherwise would not need to. However, it turns out that the only two new allocations required are: 1. In test-date.c, where we don't care about efficiency. 2. In determine_author_info, which is not performance critical (and where the use of a strbuf will help later refactoring). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-17i18n: fix uncatchable comments for translators in date.cJiang Xin1-1/+1
Comment for l10n translators can not be extracted by xgettext if it is not right above the l10n tag. Moving the comment right before the l10n tag will fix this issue. Reported-by: Brian Gesiak <modocache@gmail.com> Signed-off-by: Jiang Xin <worldhello.net@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-03-14Merge branch 'jk/commit-dates-parsing-fix'Junio C Hamano1-2/+21
Tighten codepaths that parse timestamps in commit objects. * jk/commit-dates-parsing-fix: show_ident_date: fix tz range check log: do not segfault on gmtime errors log: handle integer overflow in timestamps date: check date overflow against time_t fsck: report integer overflow in author timestamps t4212: test bogus timestamps with git-log
2014-02-24log: do not segfault on gmtime errorsJeff King1-2/+4
Many code paths assume that show_date and show_ident_date cannot return NULL. For the most part, we handle missing or corrupt timestamps by showing the epoch time t=0. However, we might still return NULL if gmtime rejects the time_t we feed it, resulting in a segfault. Let's catch this case and just format t=0. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24date: check date overflow against time_tJeff King1-0/+17
When we check whether a timestamp has overflowed, we check only against ULONG_MAX, meaning that strtoul has overflowed. However, we also feed these timestamps to system functions like gmtime, which expect a time_t. On many systems, time_t is actually smaller than "unsigned long" (e.g., because it is signed), and we would overflow when using these functions. We don't know the actual size or signedness of time_t, but we can easily check for truncation with a simple assignment. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-10-30Merge branch 'jk/date-c-double-semicolon'Junio C Hamano1-1/+1
* jk/date-c-double-semicolon: drop redundant semicolon in empty while
2013-10-24drop redundant semicolon in empty whileJeff King1-1/+1
The extra semi-colon is harmless, since we really do want the while loop to do nothing. But it does trigger a warning from clang. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-29Merge branch 'jc/prune-all'Junio C Hamano1-0/+22
We used the approxidate() parser for "--expire=<timestamp>" options of various commands, but it is better to treat --expire=all and --expire=now a bit more specially than using the current timestamp. Update "git gc" and "git reflog" with a new parsing function for expiry dates. * jc/prune-all: prune: introduce OPT_EXPIRY_DATE() and use it api-parse-options.txt: document "no-" for non-boolean options git-gc.txt, git-reflog.txt: document new expiry options date.c: add parse_expiry_date()
2013-04-17date.c: add parse_expiry_date()Junio C Hamano1-0/+22
"git reflog --expire=all" tries to expire reflog entries up to the current second, because the approxidate() parser gives the current timestamp for anything it does not understand (and it does not know what time "all" means). When the user tells us to expire "all" (or set the expiration time to "now"), the user wants to remove all the reflog entries (no reflog entry should record future time). Just set it to ULONG_MAX and to let everything that is older that timestamp expire. While at it, allow "now" to be treated the same way for callers that parse expiry date timestamp with this function. Also use an error reporting version of approxidate() to report misspelled date. When the user says e.g. "--expire=mnoday" to delete entries two days or older on Wednesday, we wouldn't want the "unknown, default to now" logic to kick in. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-25Fix time offset calculation in case of unsigned time_tMike Gorchak1-2/+8
Fix time offset calculation expression in case if time_t is unsigned. This code works fine for signed and unsigned time_t. Signed-off-by: Mike Gorchak <mike.gorchak.qnx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-25date.c: fix unsigned time_t comparisonMike Gorchak1-1/+1
tm_to_time_t() returns (time_t)-1 when it sees an error. On platforms with unsigned time_t, this value will be larger than any valid timestamp and will break the "Is this older than 10 days in the future?" check. Signed-off-by: Mike Gorchak <mike.gorchak.qnx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-07-22Merge branch 'jc/maint-filter-branch-epoch-date'Junio C Hamano1-1/+1
In 1.7.9 era, we taught "git rebase" about the raw timestamp format but we did not teach the same trick to "filter-branch", which rolled a similar logic on its own. Because of this, "filter-branch" failed to rewrite commits with ancient timestamps. * jc/maint-filter-branch-epoch-date: t7003: add test to filter a branch with a commit at epoch date.c: Fix off by one error in object-header date parsing filter-branch: do not forget the '@' prefix to force git-timestamp
2012-07-12date.c: Fix off by one error in object-header date parsingJunio C Hamano1-1/+1
It is perfectly OK for a valid decimal integer to begin with '9' but 116eb3a (parse_date(): allow ancient git-timestamp, 2012-02-02) did not express the range correctly. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-24i18n: mark relative dates for translationJonathan Nieder1-39/+56
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-10Merge branch 'jc/parse-date-raw'Junio C Hamano1-0/+30
* jc/parse-date-raw: parse_date(): '@' prefix forces git-timestamp parse_date(): allow ancient git-timestamp
2012-02-03parse_date(): '@' prefix forces git-timestampJunio C Hamano1-1/+2
The only place that the issue this series addresses was observed where we read "cat-file commit" output and put it in GIT_AUTHOR_DATE in order to replay a commit with an ancient timestamp. With the previous patch alone, "git commit --date='20100917 +0900'" can be misinterpreted to mean an ancient timestamp, not September in year 2010. Guard this codepath by requring an extra '@' in front of the raw git timestamp on the parsing side. This of course needs to be compensated by updating get_author_ident_from_commit and the code for "git commit --amend" to prepend '@' to the string read from the existing commit in the GIT_AUTHOR_DATE environment variable. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-03parse_date(): allow ancient git-timestampJunio C Hamano1-0/+29
The date-time parser parses out a human-readble datestring piece by piece, so that it could even parse a string in a rather strange notation like 'noon november 11, 2005', but restricts itself from parsing strings in "<seconds since epoch> <timezone>" format only for reasonably new timestamps (like 1974 or newer) with 10 or more digits. This is to prevent a string like "20100917" from getting interpreted as seconds since epoch (we want to treat it as September 17, 2010 instead) while doing so. The same codepath is used to read back the timestamp that we have already recorded in the headers of commit and tag objects; because of this, such a commit with timestamp "0 +0000" cannot be rebased or amended very easily. Teach parse_date() codepath to special case a string of the form "<digits> +<4-digits>" to work this issue around, but require that there is no other cruft around the string when parsing a timestamp of this format for safety. Note that this has a slight backward incompatibility implications. If somebody writes "git commit --date='20100917 +0900'" and wants it to mean a timestamp in September 2010 in Japan, this change will break such a use case. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-09-12date.c: Support iso8601 timezone formatsHaitao Li1-11/+23
Timezone designators in the following formats are all valid according to ISO8601:2004, section 4.3.2: [+-]hh, [+-]hhmm, [+-]hh:mm but we have ignored the ones with colon so far. Signed-off-by: Haitao Li <lihaitao@gmail.com> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-04-20date: avoid "X years, 12 months" in relative datesMichael J Gruber1-2/+3
When relative dates are more than about a year ago, we start writing them as "Y years, M months". At the point where we calculate Y and M, we have the time delta specified as a number of days. We calculate these integers as: Y = days / 365 M = (days % 365 + 15) / 30 This rounds days in the latter half of a month up to the nearest month, so that day 16 is "1 month" (or day 381 is "1 year, 1 month"). We don't round the year at all, though, meaning we can end up with "1 year, 12 months", which is silly; it should just be "2 years". Implement this differently with months of size onemonth = 365/12 so that totalmonths = (long)( (days + onemonth/2)/onemonth ) years = totalmonths / 12 months = totalmonths % 12 In order to do this without floats, we write the first formula as totalmonths = (days*12*2 + 365) / (365*2) Tests and inspiration by Jeff King. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-07-15Export parse_date_basic() to convert a date string to timestampJonathan Nieder1-8/+6
approxidate() is not appropriate for reading machine-written dates because it guesses instead of erroring out on malformed dates. parse_date() is less convenient since it returns its output as a string. So export the underlying function that writes a timestamp. While at it, change the return value to match the usual convention: return 0 for success and -1 for failure. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Acked-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-07-05parse_date: fix signedness in timezone calculationJeff King1-1/+1
When no timezone is specified, we deduce the offset by subtracting the result of mktime from our calculated timestamp. However, our timestamp is stored as an unsigned integer, meaning we perform the subtraction as unsigned. For a negative offset, this means we wrap to a very high number, and our numeric timezone is in the millions of hours. You can see this bug by doing: $ TZ=EST \ GIT_AUTHOR_DATE='2010-06-01 10:00' \ git commit -a -m foo $ git cat-file -p HEAD | grep author author Jeff King <peff@peff.net> 1275404416 +119304128 Instead, we should perform this subtraction as a time_t, the same type that mktime returns. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-06-21Merge branch 'rr/parse-date-refactor'Junio C Hamano1-19/+37
* rr/parse-date-refactor: Refactor parse_date for approxidate functions
2010-06-07Refactor parse_date for approxidate functionsRamkumar Ramachandra1-19/+37
approxidate_relative and approxidate_careful both use parse_date to dump the timestamp to a character buffer and parse it back into a long unsigned using strtoul(). Avoid doing this by creating a new parse_date_toffset method. Noticed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-18Add "Z" as an alias for the timezone "UTC"Marcus Comstedt1-1/+2
The name "Z" for the UTC timezone is required to properly parse ISO 8601 timestamps. Add it to the list of recognized timezones. Because timezone names can be shorter than 3 letters, loosen the restriction in match_alpha() that used to require at least 3 letters to match to allow a short timezone name as long as it matches exactly. Prior to the introduction of the "Z" zone, this already affected the timezone "NT" (Nome). Signed-off-by: Marcus Comstedt <marcus@mc.pp.se> Reviewed-by: Jay Soffian <jaysoffian@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-27Merge branch 'jc/maint-reflog-bad-timestamp'Junio C Hamano1-8/+35
* jc/maint-reflog-bad-timestamp: t0101: use a fixed timestamp when searching in the reflog Update @{bogus.timestamp} fix not to die() approxidate_careful() reports errorneous date string
2010-01-26approxidate_careful() reports errorneous date stringJunio C Hamano1-8/+35
For a long time, the time based reflog syntax (e.g. master@{yesterday}) didn't complain when the "human readable" timestamp was misspelled, as the underlying mechanism tried to be as lenient as possible. The funny thing was that parsing of "@{now}" even relied on the fact that anything not recognized by the machinery returned the current timestamp. Introduce approxidate_careful() that takes an optional pointer to an integer, that gets assigned 1 when the input does not make sense as a timestamp. As I am too lazy to fix all the callers that use approxidate(), most of the callers do not take advantage of the error checking, but convert the code to parse reflog to use it as a demonstration. Tests are mostly from Jeff King. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-20date.c: mark file-local function staticJunio C Hamano1-1/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-10-03Fix '--relative-date'Johan Sageryd1-1/+1
This fixes '--relative-date' so that it does not give '0 year, 12 months', for the interval 360 <= diff < 365. Signed-off-by: Johan Sageryd <j416@1616.se> Signed-off-by: Jeff King <peff@peff.net>
2009-08-30fix approxidate parsing of relative months and yearsJeff King1-1/+4
These were broken by b5373e9. The problem is that the code marks the month and year with "-1" for "we don't know it yet", but the month and year code paths were not adjusted to fill in the current time before doing their calculations (whereas other units follow a different code path and are fine). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-30Add date formatting and parsing functions relative to a given timeAlex Riesen1-63/+87
The main purpose is to allow predictable testing of the code. Signed-off-by: Alex Riesen <raa.lkml@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-22Further 'approxidate' improvementsLinus Torvalds1-5/+27
The previous patch to improve approxidate got us to the point that a lot of the remaining annoyances were due to the 'strict' date handling running first, and deciding that it got a good enough date that the approximate date routines were never even invoked. For example, using a date string like 6AM, June 7, 2009 the strict date logic would be perfectly happy with the "June 7, 2009" part, and ignore the 6AM part that it didn't understand - resulting in the information getting dropped on the floor: 6AM, June 7, 2009 -> Sat Jun 6 00:00:00 2009 and the date being calculated as if it was midnight, and the '6AM' having confused the date routines into thinking about '6 June' rather than 'June 7' at 6AM (ie notice how the _day_ was wrong due to this, not just the time). So this makes the strict date routines a bit stricter, and requires that not just the date, but also the time, has actually been parsed. With that fix, and trivial extension of the approxidate routines, git now properly parses the date as 6AM, June 7, 2009 -> Sun Jun 7 06:00:00 2009 without dropping the fuzzy time ("6AM" or "noon" or any of the other non-strict time formats) on the floor. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-22Improve on 'approxidate'Linus Torvalds1-30/+63
This is not a new failure mode - approxidate has always been kind of random in the input it accepts, but some of the randomness is more irritating than others. For example: Jun 6, 5AM -> Mon Jun 22 05:00:00 2009 5AM Jun 6 -> Sat Jun 6 05:00:00 2009 Whaa? The reason for the above is that approxidate squirrells away the '6' from "Jun 6" to see if it's going to be a relative number, and then forgets about it when it sees a new number (the '5' in '5AM'). So the odd "June 22" date is because today is July 22nd, and if it doesn't have another day of the month, it will just pick todays mday - having ignored the '6' entirely due to getting all excited about seeing a new number (5). There are other oddnesses. This does not fix them all, but I think it makes for fewer _really_ perplexing cases. At least now we have Jun 6, 5AM -> Sat Jun 6 05:00:00 2009 5AM, Jun 6 -> Sat Jun 6 05:00:00 2009 which makes me happier. I can still point to cases that don't work as well, but those are separate issues. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-05Work around BSD whose typeof(tv.tv_sec) != time_tBernd Ahlers1-1/+3
According to POSIX, tv_sec is supposed to be a time_t, but OpenBSD (and FreeBSD, too) defines it to be a long, which triggers a type mismatch when a pointer to it is given to localtime_r(). Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-25never fallback relative times to absoluteJeff King1-1/+19
Previously, for dates older than 12 months we fell back to just giving the absolute time. This can be a bit jarring when reading a list of times. Instead, let's switch to "Y years, M months" for five years, and then just "Y years" after that. No particular reason on the 5 year cutoff except that it seemed reasonable to me. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-20Support 'raw' date formatLinus Torvalds1-0/+7
Talking about --date, one thing I wanted for the 1234567890 date was to get things in the raw format. Sure, you get them with --pretty=raw, but it felt a bit sad that you couldn't just ask for the date in raw format. So here's a throw-away patch (meaning: I won't be re-sending it, because I really don't think it's a big deal) to add "--date=raw". It just prints out the internal raw git format - seconds since epoch plus timezone (put another way: 'date +"%s %z"' format) Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-17date/time: do not get confused by fractional secondsLinus Torvalds1-6/+20
The date/time parsing code was confused if the input time HH:MM:SS is followed by fractional seconds. Since we do not record anything finer grained than seconds, we could just drop fractional part, but there is a twist. We have taught people that not just spaces but dot can be used as word separators when spelling things like: $ git log --since 2.days $ git show @{12:34:56.7.days.ago} and we shouldn't mistake "7" in the latter example as a fraction and discard it. The rules are: - valid days of month/mday are always single or double digits. - valid years are either two or four digits No, we don't support the year 600 _anyway_, since our encoding is based on the UNIX epoch, and the day we worry about the year 10,000 is far away and we can raise the limit to five digits when we get closer. - Other numbers (eg "600 days ago") can have any number of digits, but they cannot start with a zero. Again, the only exception is for two-digit numbers, since that is fairly common for dates ("Dec 01" is not unheard of) So that means that any milli- or micro-second would be thrown out just because the number of digits shows that it cannot be an interesting date. A milli- or micro-second can obviously be a perfectly fine number according to the rules above, as long as it doesn't start with a '0'. So if we have 12:34:56.123 then that '123' gets parsed as a number, and we remember it. But because it's bigger than 31, we'll never use it as such _unless_ there is something after it to trigger that use. So you can say "12:34:56.123.days.ago", and because of the "days", that 123 will actually be meaninful now. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-23Make my_mktime() public and rename it to tm_to_time_t()Johannes Sixt1-5/+8
We will use it from the MinGW port's gettimeofday() substitution. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
2008-06-17Fix approxidate("never") to always return 0Olivier Marin1-4/+2
Commit af66366a9feb0194ed04b1f538998021ece268a8 introduced the keyword "never" to be used with approxidate() but defined it with a fixed date without taking care of timezone. As a result approxidate() will return a timestamp in the future with a negative timezone. With this patch, approxidate("never") always return 0 whatever your timezone is. Signed-off-by: Olivier Marin <dkr@freesurf.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-25timezone_names[]: fixed the tz offset for New Zealand.Steven Drake1-3/+3
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-09-29parse_date_format(): convert a format name to an enum date_modeAndy Parkins1-0/+20
Factor out the code to parse --date=<format> parameter to revision walkers into a separate function, parse_date_format(). This function is passed a string and converts it to an enum date_format: - "relative" => DATE_RELATIVE - "iso8601" or "iso" => DATE_ISO8601 - "rfc2822" => DATE_RFC2822 - "short" => DATE_SHORT - "local" => DATE_LOCAL - "default" => DATE_NORMAL In the event that none of these strings is found, the function die()s. Signed-off-by: Andy Parkins <andyparkins@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-24Teach approxidate() to understand "never"Johannes Schindelin1-0/+9
If you want to keep the reflogs around for a really long time, you should be able to say so: $ git config gc.reflogExpire never Now it works, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-13Make show_rfc2822_date() just another date output format.Junio C Hamano1-15/+5
These days, show_date() takes a date_mode parameter to specify the output format, and a separate specialized function for dates in E-mails does not make much sense anymore. This retires show_rfc2822_date() function and make it just another date output format. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-07-13Support output ISO 8601 format datesRobin Rosenberg1-0/+7
Support output of full ISO 8601 style dates in e.g. git log and other places that use interpolation for formatting. Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-06-07War on whitespaceJunio C Hamano1-5/+5
This uses "git-apply --whitespace=strip" to fix whitespace errors that have crept in to our source files over time. There are a few files that need to have trailing whitespaces (most notably, test vectors). The results still passes the test, and build result in Documentation/ area is unchanged. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-06-06Accept dates before 2000/01/01 when specified as seconds since the epochJohannes Sixt1-2/+4
Tests with git-filter-branch on a repository that was converted from CVS and that has commits reaching back to 1999 revealed that it is necessary to parse dates before 2000/01/01 when they are specified as seconds since 1970/01/01. There is now still a limit, 100000000, which is 1973/03/03 09:46:40 UTC, in order to allow that dates are represented as 8 digits. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-04-25Add --date={local,relative,default}Junio C Hamano1-2/+33
This adds --date={local,relative,default} option to log family of commands, to allow displaying timestamps in user's local timezone, relative time, or the default format. Existing --relative-date option is a synonym of --date=relative; we could probably deprecate it in the long run. Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-02-27show_date(): rename the "relative" parameter to "mode"Johannes Schindelin1-8/+12
Now, show_date() can print three different kinds of dates: normal, relative and short (%Y-%m-%s) dates. To achieve this, the "int relative" was changed to "enum date_mode mode", which has three states: DATE_NORMAL, DATE_RELATIVE and DATE_SHORT. Since existing users of show_date() only call it with relative_date being either 0 or 1, and DATE_NORMAL and DATE_RELATIVE having these values, no behaviour is changed. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-20show_date(): fix relative datesJohannes Schindelin1-3/+2
We pass a timestamp (i.e. number of seconds elapsed since Jan 1 1970, 00:00:00 GMT) to the function. So there is no need to "fix" the timestamp according to the timezone. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
2006-12-20simplify inclusion of system header files.Junio C Hamano1-3/+0
This is a mechanical clean-up of the way *.c files include system header files. (1) sources under compat/, platform sha-1 implementations, and xdelta code are exempt from the following rules; (2) the first #include must be "git-compat-util.h" or one of our own header file that includes it first (e.g. config.h, builtin.h, pkt-line.h); (3) system headers that are included in "git-compat-util.h" need not be included in individual C source files. (4) "git-compat-util.h" does not have to include subsystem specific header files (e.g. expat.h). Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-29Fix approxidate() to understand 12:34 AM/PM are 00:34 and 12:34Linus Torvalds1-10/+16
It just simplifies the whole thing to say "hour = (hour % 12) + X" where X is 12 for PM and 0 for AM. It also fixes the "exact date" parsing, which didn't parse AM at all, and as such would do the same "12:30 AM" means "12:30 24-hour-format" bug. Of course, I hope that no exact dates use AM/PM anyway, but since we support the PM format, let's just get it right. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-28Fix approxidate() to understand more extended numbersLinus Torvalds1-0/+40
You can now say "5:35 PM yesterday", and approxidate() gets the right answer. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-28Clean up approxidate() in preparation for fixesLinus Torvalds1-3/+10
Our approxidate cannot handle simple times like "5 PM yesterday", and to fix that, we will need to add some logic for number handling. This just splits that out into a function of its own (the same way the _real_ date parsing works). Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-26Relative timestamps in git logLinus Torvalds1-8/+55
I noticed that I was looking at the kernel gitweb output at some point rather than just do "git log", simply because I liked seeing the simplified date-format, ie the "5 days ago" rather than a full date. This adds infrastructure to do that for "git log" too. It does NOT add the actual flag to enable it, though, so right now this patch is a no-op, but it should now be easy to add a command line flag (and possibly a config file option) to just turn on the "relative" date format. The exact cut-off points when it switches from days to weeks etc are totally arbitrary, but are picked somewhat to avoid the "1 weeks ago" thing (by making it show "10 days ago" rather than "1 week", or "70 minutes ago" rather than "1 hour ago"). [jc: with minor fix and tweak around "month" and "week" area.] Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-23n is in fact unused, and is later shadowed.Pierre Habouzit1-3/+3
date.c::approxidate_alpha() counts the number of alphabets while moving the pointer but does not use the count. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-08date.c: improve guess between timezone offset and year.Paul Eggert1-1/+1
When match_digit() guesses a four-digit string to tell if it is a year or a timezone, it did not consider that some real-world places have UTC offsets equal to +1400. $ date; TZ=UTC0 date; TZ=Pacific/Kiritimati date Wed Jun 7 23:25:42 PDT 2006 Thu Jun 8 06:25:42 UTC 2006 Thu Jun 8 20:25:42 LINT 2006 Signed-off-by: Paul Eggert <eggert@CS.UCLA.EDU> Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-05-01Use RFC2822 dates from "git fmt-patch".Junio C Hamano1-4/+25
Still Work-in-progress git fmt-patch (should it be known as format-patch-ng?) is matched with the fix made by Huw Davies in 262a6ef76a1dde97ab50d79fa5cd6d3f9f125765 commit to use RFC2822 date format. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-05date parsing: be friendlier to our European friends.Junio C Hamano1-21/+56
This does three things, only applies to cases where the user manually tries to override the author/commit time by environment variables, with non-ISO, non-2822 format date-string: - Refuses to use the interpretation to put the date in the future; recent kernel history has a commit made with 10/03/2006 which is recorded as October 3rd. - Adds '.' as the possible year-month-date separator. We learned from our European friends on the #git channel that dd.mm.yyyy is the norm there. - When the separator is '.', we prefer dd.mm.yyyy over mm.dd.yyyy; otherwise mm/dd/yy[yy] takes precedence over dd/mm/yy[yy]. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-05Merge branch 'fix'Junio C Hamano1-2/+2
* fix: diff_flush(): leakfix. parse_date(): fix parsing 03/10/2006
2006-04-04parse_date(): fix parsing 03/10/2006Junio C Hamano1-2/+2
The comment associated with the date parsing code for three numbers separated with slashes or dashes implied we wanted to interpret using this order: yyyy-mm-dd yyyy-dd-mm mm-dd-yy dd-mm-yy However, the actual code had the last two wrong, and making it prefer dd-mm-yy format over mm-dd-yy. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-03-09Use #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))Junio C Hamano1-3/+1
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-05Fix nasty approxidate bugLinus Torvalds1-1/+1
Stupid me. If approxidate ends up with a month that is ahead of the current month, it decrements the year to last year. Which is correct, and means that "last december" does the right thing. HOWEVER. It should only do so if the year is the same as the current year. Without this fix, "5 days ago" ends up being in 2004, because it first decrements five days, getting us to December 2005 (correct), but then it also ends up decrementing the year once more to turn that December into "last year" (incorrect, since it already _was_ last year). Duh. Pass me a donut. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-12-29code comments: spellJunio C Hamano1-1/+1
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18Teach "approxidate" about weekday syntaxLinus Torvalds1-5/+49
On Fri, 18 Nov 2005, David Roundy wrote: > > Don't forget "high noon"! (and perhaps "tea time"?) :) Done. [torvalds@g5 git]$ ./test-date "now" "midnight" "high noon" "tea-time" now -> bad -> Wed Dec 31 16:00:00 1969 now -> Fri Nov 18 08:50:54 2005 midnight -> bad -> Wed Dec 31 16:00:00 1969 midnight -> Fri Nov 18 00:00:00 2005 high noon -> bad -> Wed Dec 31 16:00:00 1969 high noon -> Thu Nov 17 12:00:00 2005 tea-time -> bad -> Wed Dec 31 16:00:00 1969 tea-time -> Thu Nov 17 17:00:00 2005 Thanks for pointing out tea-time. This is also written to easily extended to allow people to add their own important dates like Christmas and their own birthdays. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17Teach "approxidate" about weekday syntaxLinus Torvalds1-1/+17
This allows people to use syntax like "last thursday" for the approxidate. (Or, indeed, more complex "three thursdays ago", but I suspect that would be pretty unusual). NOTE! The parsing is strictly sequential, so if you do "one day before last thursday" it will _not_ do what you think it does. It will take the current time, subtract one day, and then go back to the thursday before that. So to get what you want, you'd have to write it the other way around: "last thursday and one day before" which is insane (it's usually the same as "last wednesday" _except_ if today is Thursday, in which case "last wednesday" is yesterday, and "last thursday and one day before" is eight days ago). Similarly, "last thursday one month ago" will first go back to last thursday, and then go back one month from there, not the other way around. I doubt anybody would ever use insane dates like that, but I thought I'd point out that the approxidate parsing is not exactly "standard English". Side note 2: if you want to avoid spaces (because of quoting issues), you can use any non-alphanumberic character instead. So git log --since=2.days.ago works without any quotes. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16git's rev-parse.c function show_datestring presumes gnu dateLinus Torvalds1-0/+124
Ok. This is the insane patch to do this. It really isn't very careful, and the reason I call it "approxidate()" will become obvious when you look at the code. It is very liberal in what it accepts, to the point where sometimes the results may not make a whole lot of sense. It accepts "last week" as a date string, by virtue of "last" parsing as the number 1, and it totally ignoring superfluous fluff like "ago", so "last week" ends up being exactly the same thing as "1 week ago". Fine so far. It has strange side effects: "last december" will actually parse as "Dec 1", which actually _does_ turn out right, because it will then notice that it's not December yet, so it will decide that you must be talking about a date last year. So it actually gets it right, but it's kind of for the "wrong" reasons. It also accepts the numbers 1..10 in string format ("one" .. "ten"), so you can do "ten weeks ago" or "ten hours ago" and it will do the right thing. But it will do some really strange thigns too: the string "this will last forever", will not recognize anyting but "last", which is recognized as "1", which since it doesn't understand anything else it will think is the day of the month. So if you do gitk --since="this will last forever" the date will actually parse as the first day of the current month. And it will parse the string "now" as "now", but only because it doesn't understand it at all, and it makes everything relative to "now". Similarly, it doesn't actually parse the "ago" or "from now", so "2 weeks ago" is exactly the same as "2 weeks from now". It's the current date minus 14 days. But hey, it's probably better (and certainly faster) than depending on GNU date. So now you can portably do things like gitk --since="two weeks and three days ago" git log --since="July 5" git-whatchanged --since="10 hours ago" git log --since="last october" and it will actually do exactly what you thought it would do (I think). It will count 17 days backwards, and it will do so even if you don't have GNU date installed. (I don't do "last monday" or similar yet, but I can extend it to that too if people want). It was kind of fun trying to write code that uses such totally relaxed "understanding" of dates yet tries to get it right for the trivial cases. The result should be mixed with a few strange preprocessor tricks, and be submitted for the IOCCC ;) Feel free to try it out, and see how many strange dates it gets right. Or wrong. And if you find some interesting (and valid - not "interesting" as in "strange", but "interesting" as in "I'd be interested in actually doing this) thing it gets wrong - usually by not understanding it and silently just doing some strange things - please holler. Now, as usual this certainly hasn't been getting a lot of testing. But my code always works, no? Linus Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-14Unlocalized isspace and friendsLinus Torvalds1-1/+0
Do our own ctype.h, just to get the sane semantics: we want locale-independence, _and_ we want the right signed behaviour. Plus we only use a very small subset of ctype.h anyway (isspace, isalpha, isdigit and isalnum). Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-22[PATCH] Fix strange timezone handlingLinus Torvalds1-10/+14
We generate the ASCII representation of our internal date representation ("seconds since 1970, UTC + timezone information") in two different places. One of them uses the stupid and obvious way to make sure that it gets the sexagecimal representation right for negative timezones even if they might not be exact hours, and the other one depends on the modulus operator always matching the sign of argument. Hey, the clever one works. And C90 even specifies that behaviour. But I had to think about it for a while when I was re-visiting this area, and even if I didn't have to, it's kind of strange to have two different ways to print out the same data format. So use a common helper for this. And select the stupid and straighforward way. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-20[PATCH] Return proper error valud from "parse_date()"Linus Torvalds1-3/+3
Right now we don't return any error value at all from parse_date(), and if we can't parse it, we just silently leave the result buffer unchanged. That's fine for the current user, which will always default to the current date, but it's a crappy interface, and we might well be better off with an error message rather than just the default date. So let's change the thing to return a negative value if an error occurs, and the length of the result otherwise (snprintf behaviour: if the buffer is too small, it returns how big it _would_ have been). [ I started looking at this in case we could support date-based revision names. Looks ugly. Would have to parse relative dates.. ] Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-07-12parse_date(): allow const date stringLinus Torvalds1-4/+4
This is part of breaking up the tag ID patch by Eric Biederman.
2005-06-25[PATCH] fix date parsing for GIT raw commit timestamp format.Junio C Hamano1-5/+9
Usually all of the match_xxx routines in date.c fill tm structure assuming that the parsed string talks about local time, and parse_date routine compensates for it by adjusting the value with tz offset parsed out separately. However, this logic does not work well when we feed GIT raw commit timestamp to it, because what match_digits gets is already in GMT. A good testcase is: $ make test-date $ ./test-date 'Fri Jun 24 16:55:27 2005 -0700' '1119657327 -0700' These two timestamps represent the same time, but the second one without the fix this commit introduces gives you 7 hours off. Signed-off-by: Junio C Hamano <junkio@cox.net> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-22Include file cleanups..Linus Torvalds1-3/+0
Add <limits.h> to the include files handled by "cache.h", and remove extraneous #include directives from various .c files. The rule is that "cache.h" gets all the basic stuff, so that we'll have as few system dependencies as possible.
2005-05-20sparse cleanupLinus Torvalds1-0/+2
Fix various things that sparse complains about: - use NULL instead of 0 - make sure we declare everything properly, or mark it static - use proper function declarations ("fn(void)" instead of "fn()") Sparse is always right.
2005-05-18[PATCH] fix show_date() for positive timezonesNicolas Pitre1-2/+2
Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-06date.c: add "show_date()" function.Linus Torvalds1-0/+28
Kind of like ctime(), but not as broken.
2005-05-01date handling: handle "AM"/"PM" on timeLinus Torvalds1-8/+22
And be a bitmore careful about matching: if we don't recognize a word or a number, we skip the whole thing, rather than trying the next character in that word/number. Finally: since ctime() adds the final '\n', don't add another one in test-date.
2005-05-01date.c: allow even more varied time formatsLinus Torvalds1-54/+152
(and some added checks for truly non-sensical stuff)
2005-04-30date.c: fix printout of timezone offsets that aren't exact hoursLinus Torvalds1-2/+8
We'd get the sign wrong for the minutes part of a negative offset.
2005-04-30date.c: only use the TZ names if we don't have anything better.Linus Torvalds1-1/+5
Also, add EEST (hey, it's Finland).
2005-04-30date.c: split up dst information in the timezone tableLinus Torvalds1-45/+51
This still doesn't actually really _use_ it properly, nor make any distinction between different DST rules, but at least we could (if we wanted to) fake it a bit better. Right now the code actually still says "it's always summer". I'm from Finland, I don't like winter.
2005-04-30date.c: fix parsing of dates in mm/dd/yy formatLinus Torvalds1-1/+3
We looked at the year one character too early, and we didn't accept a two-character year date after 2000.
2005-04-30date.c: use the local timezone if none specifiedLinus Torvalds1-2/+7
2005-04-30Make the date parsing accept pretty much any random crap.Linus Torvalds1-106/+215
This date parser turns line-noise into a date. Cool.
2005-04-30[PATCH] Do date parsing by hand...Edgar Toernig1-0/+184
...since everything out there is either strange (libc mktime has issues with timezones) or introduces unnecessary dependencies for people (libcurl). This goes back to the old date parsing, but moves it out into a file of its own, and does the "struct tm" to "seconds since epoch" handling by hand. I grepped through the tz-database and it seems there's one "country" left that has non-60-minute DST: Lord Howe Island. All others dropped that before 1970.