jfh@rpp386.cactus.org (John F. Haugh II) (11/26/90)
In article <1948@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes: >Here's a mktime() sort of thing based on calling localtime(3) and >binary chopping on a guessed UNIX time long. Ok? gack! you can compute it directly without looping. if you don't care about daylight savings time corrections you can get it without ever having to call localtime. this is what i use in "chage" to compute "days since the epoch". don't forget to multiply by (3600*24) to get seconds. i've not completely debugged this fragment - it is part of the next version of that command. -- slice and dice as needed ... -- /* * Copyright 1990, John F. Haugh II * All rights reserved. * * Use, duplication, and disclosure prohibited without * the express written permission of the author. */ #include <sys/types.h> #include <time.h> /* * days and juldays are used to compute the number of days in the * current month, and the cummulative number of days in the preceding * months. they are declared so that january is 1, not 0. */ static short days[13] = { 0, 31, 28, 31, 30, 31, 30, /* JAN - JUN */ 31, 31, 30, 31, 30, 31 }; /* JUL - DEC */ static short juldays[13] = { 0, 0, 31, 59, 90, 120, 151, /* JAN - JUN */ 181, 212, 243, 273, 304, 334 }; /* JUL - DEC */ /* * strtoday - compute the number of days since 1970. * * the total number of days prior to the current date is * computed. january 1, 1970 is used as the origin with * it having a day number of 0. the gmtime() routine is * used to prevent confusion regarding time zones. */ long strtoday (str) char *str; { int month; int day; int year; long total; /* * start by separating the month, day and year. this is * a chauvanistic program - it only takes date input in * the standard USA format. */ if (sscanf (str, "%d/%d/%d", &month, &day, &year) != 3) return -1; /* * the month, day of the month, and year are checked for * correctness and the year adjusted so it falls between * 1970 and 2069. */ if (month < 1 || month > 12) return -1; if (day < 1) return -1; if ((month != 2 || (year % 4) != 0) && day > days[month]) return -1; else if (day > 29) return -1; if (year < 0) return -1; else if (year < 70) year += 2000; else if (year < 99) year += 1900; if (year < 1970 || year > 2069) return -1; /* * the total number of days is the total number of days in all * the whole years, plus the number of leap days, plus the * number of days in the whole months preceding, plus the number * of days so far in the month. */ total = ((year - 1970) * 365) + (((year + 1) - 1970) / 4); total += juldays[month] + (month > 2 && (year % 4) == 0 ? 1:0); total += day - 1; return total; } -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "SCCS, the source motel! Programs check in and never check out!" -- Ken Thompson
boyd@necisa.ho.necisa.oz (Boyd Roberts) (11/28/90)
In article <18748@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: > >gack! you can compute it directly without looping. if you don't >care about daylight savings time corrections you can get it without >ever having to call localtime. > Yeah, just what the guy wanted. Bugger correctness -- I mean you wouldn't want to write code that was actually _correct_, would you now? ``As long as you don't care that it works'' -- a truly fine philosophy. Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''
xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) (11/28/90)
boyd@necisa.ho.necisa.oz (Boyd Roberts) writes in alt.sources.d: > jfh@rpp386.cactus.org (John F. Haugh II) writes: >>gack! you can compute it directly without looping. if you don't >>care about daylight savings time corrections you can get it without >>ever having to call localtime. >Yeah, just what the guy wanted. Bugger correctness -- I mean you wouldn't >want to write code that was actually _correct_, would you now? >``As long as you don't care that it works'' -- a truly fine philosophy. Yep, that's our John Haugh. Any wonder, with coding habits like that, that he needs and is promoting the return of comp.unix.wizards, so he can have an audience unskilled enough to think of him as a real programmer? The scary thing is that he earns his living as a coding consultant, when he's not busy libeling people on the net or making a fool of himself all over the place. Kent, the man from xanth. <xanthian@Zorch.SF-Bay.ORG> <xanthian@well.sf.ca.us>
jfh@rpp386.cactus.org (John F. Haugh II) (11/28/90)
In article <1949@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes: >In article <18748@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >>gack! you can compute it directly without looping. if you don't >>care about daylight savings time corrections you can get it without >>ever having to call localtime. > >Yeah, just what the guy wanted. Bugger correctness -- I mean you wouldn't >want to write code that was actually _correct_, would you now? Your algorithm makes 31 calls to localtime because it has to figure out (2 ^ 31) possible dates by binary decomposition. Let's pretend for a moment that my algorithm takes as much time as one call to localtime() to get the initial guess. Now the code gets within 1 day of the correct time, which is 86,400 seconds. It would take ceil(Log2(86,400)) = 17 calls to localtime to resolve the hard way, or ceil(Log2(24)) = 5 if you do it cleverly. Adding in the fudge factor means taking a bad guess saves you about 40%, and being cleverer saves you about 80%, or roughly 5 times as fast. >``As long as you don't care that it works'' -- a truly fine philosophy. Hey, you can always take the guess my algorithm produces and plug it into your little binary guess thingy. Of course, you don't actually need to completely figure it out, just figure if daylight savings time came or went that day. It is rumored that a major vendor once had a FORTRAN integer square root routine which was coded as (modulo syntax errors and such) INTEGER FUNCTION SQRT (N) DO 100 I = 1,65535 IF I * I .GT. N RETURN I - 1 100 CONTINUE RETURN 0 Hey - it also worked. It just took a little longer. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "SCCS, the source motel! Programs check in and never check out!" -- Ken Thompson
Sm@cerberus.bhpese.oz.au (Scott Merrilees) (11/29/90)
In article <18748@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >gack! you can compute it directly without looping. if you don't >care about daylight savings time corrections you can get it without >ever having to call localtime. But then you have to know all the garbage about when daylight savings time cuts in/out, leap years etc. This solution is simple, has a few guesses, and will work anywhere without telling it extra stuff. It may not be terribly efficient, but probably won't be called that often. I like both it, and the side step to think of doing it that way. Sm -- Scott Merrilees, BHP Information Technology, Newcastle, Australia Internet: Sm@bhpese.oz.au Phone: +61 49 402132
jfh@rpp386.cactus.org (John F. Haugh II) (11/30/90)
In article <1990Nov29.040427.15103@cerberus.bhpese.oz.au> Sm@cerberus.bhpese.oz.au (Scott Merrilees) writes: >But then you have to know all the garbage about when daylight savings >time cuts in/out, leap years etc. This solution is simple, has a >few guesses, and will work anywhere without telling it extra stuff. >It may not be terribly efficient, but probably won't be called that >often. I like both it, and the side step to think of doing it that >way. I'm really sorry that you and Gregory have decided to attack my suggestion without trying to do anything with it. The code correctly gets within 48 hours of the day you want, regardless of leap years, time zones, daylight savings time, etc. All that is left is figuring out how many hours off the guess was. That is very trivial and only requires one or two calls to localtime to get. It is very easy to figure out the difference between two very close dates, so the hours fall out very quickly. Extending to support hours, minutes and seconds is painless. Sure, the original posted solution is "correct", but then so would be starting at 0 and counting up by ones. Binary approximation is a very old technique. It is not new or clever. It is a lazy solution to a really simple problem. Clever would have been binary approximation using whole hours or days, both of which would have been an improvement and would have shown some thought. As for not being called all that often, what if the application is something like "expire" which must deal with textual dates in article headers? Still think it won't be called that often? -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "SCCS, the source motel! Programs check in and never check out!" -- Ken Thompson
jfh@rpp386.cactus.org (John F. Haugh II) (11/30/90)
In article <1990Nov28.065101.13081@zorch.SF-Bay.ORG> xanthian@zorch.SF-Bay.ORG (Kent Paul Dolan) writes: >Yep, that's our John Haugh. Any wonder, with coding habits like that, >that he needs and is promoting the return of comp.unix.wizards, so he >can have an audience unskilled enough to think of him as a real programmer? Oh great, K*nt Paul Dolan. Official net.mental-case. K*nt, haven't you had enough? =I= admit my code has bugs. Can you make the same claims? I don't know - frankly I never see code with your name on it. Okay, since K*nt cares so much, let's see what kind of interesting bugs there might be in the program which Boyd Roberts posted the other day. The advantage to admitting you have bugs in your code is that when some idiot like me comes along and points them out you get to say "Gee, Thanks" instead of eating crow because you pretended to write bug free code or pretending the problem isn't really a bug. Let's suppose for a moment that you are running your program in the central time zone. Let's suppose for a moment that you are running it on October 28th around 1:51 am. Let's suppose for a moment that you are running it for every second of that fateful minute. What you will see is that 10/28/90 01:51:44 returns 657,096,704 seconds and that 10/28/90 01:51:45 returns 657,100,305, which is hardly one second more. It is, in fact 3601 seconds more, which means that according to Boyd Roberts daylight savings time starts at 1:51:45, and not 1:00 or 2:00 or whatever. You have to understand the algorithm to understand the source of the error. The first time is 0x272A8000. When the next second rolls around, it just so happens that 0x272A8001 =doesn't= get picked because there are =two= 1:51:45's and Boyd picks the second one because 0x272AC000 is too large, and so is every choice all the way to 0x272A8800, by which time he has already skipped over (in counting order, that is) 0x272A8001. Once his algorithm decides that 0x272A8800 is too small, he is forced to pick the second occurance of that time by setting more of the bits off to the right. >The scary thing is that he earns his living as a coding consultant, when >he's not busy libeling people on the net or making a fool of himself all >over the place. No, K*nt, I make my living as a programmer. Unlike you who makes his living dodging the child support payments you are supposed to be paying to your ex-wife, or pretending to be mentally ill. You may be mentally ill, for all I know, but I've never seen anyone as "disabled" as you are "able" to produce so much crap. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "SCCS, the source motel! Programs check in and never check out!" -- Ken Thompson
boyd@necisa.ho.necisa.oz (Boyd Roberts) (12/03/90)
In article <18761@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: > >As for not being called all that often, what if the application >is something like "expire" which must deal with textual dates >in article headers? Still think it won't be called that often? That's a different problem. You'd compare the _components_ of a pieced together `struct tm', not the 32 bit UNIX time. That would be stupid. Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''