At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding?
A year has 52 weeks plus one or two days.
[snip]
Sincerely,
Gene Wirchenko
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
************************************** * Program: datestuff3.prg * Date: 05/08/2018 11:09 AM * VFP Version: Visual FoxPro 09.00.0000.7423 for Windows * Notes: ************************************** ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer) * compliments of Ted Roche * parameters: thedate: date to start from * offset: number of years offset, positive or negative * returns: nearest date to the offset that falls on the same day of the week LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding?
A year has 52 weeks plus one or two days.
[snip]
Sincerely,
Gene Wirchenko
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
Or an ICASE? (I haven't quite wrapped my head around what you're doing there but it seems like there are 3 states?)
m.theOffset=ICASE(theDiff>3, 7-m.theDiff,theDiff<-3, 7+m.theDiff, m.theDiff)
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 3:25 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
An ICASE might do it.
Basically the idea is get the day number (DOW) of the current date, like 2 for Tuesday if SET FDOW is 1 ("the first day of the week is Monday")
Then create a new date with GOMONTH() and get the day number of that, some number 1 through 7. So if the new date is a five, I want to go back 3 to get to 2. Similarly, if it's a 6, I want to go forward 3 to get to the next, closest 2.
So, you want to find the nearest matching day number: they're either the same day, so zero offset, or the matching day number are 1,2,3 days earlier or later.
so you take the difference between the original date and the new date. if the absolute difference is 3 or less, that's your offset and you use that to move the new date to the matching day number.
If the difference is -4, -5, -6 or 4, 5, 6 days, you need to look to the next/previous weeks' matching day number, hence the magic 7 number.
On Tue, May 8, 2018 at 3:39 PM, Richard Kaye rkaye@invaluable.com wrote:
Or an ICASE? (I haven't quite wrapped my head around what you're doing there but it seems like there are 3 states?)
m.theOffset=ICASE(theDiff>3, 7-m.theDiff,theDiff<-3, 7+m.theDiff, m.theDiff)
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 3:25 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
How about:
FUNCTION olddate(thedate, offset) * parameters: * the date: the source date * offset number of years offset, positive or negative * returns: the nearest date that is the same day of week as the source date
LOCAL thediff, theoffset thediff = DOW(thedate) - DOW(GOMONTH(thedate, offset*12)) theoffset = IIF(ABS(thediff)>3, 7-SIGN(thediff)*(thediff), thediff) RETURN GOMONTH(thedate, offset*12)+theoffset
ABS() only picks up the high end of the date difference, 4,5,6 SIGN() toggles whether you add or subtract the difference (minus a minus is a plus)
On Tue, May 8, 2018 at 5:03 PM, Ted Roche tedroche@gmail.com wrote:
An ICASE might do it.
Basically the idea is get the day number (DOW) of the current date, like 2 for Tuesday if SET FDOW is 1 ("the first day of the week is Monday")
Then create a new date with GOMONTH() and get the day number of that, some number 1 through 7. So if the new date is a five, I want to go back 3 to get to 2. Similarly, if it's a 6, I want to go forward 3 to get to the next, closest 2.
So, you want to find the nearest matching day number: they're either the same day, so zero offset, or the matching day number are 1,2,3 days earlier or later.
so you take the difference between the original date and the new date. if the absolute difference is 3 or less, that's your offset and you use that to move the new date to the matching day number.
If the difference is -4, -5, -6 or 4, 5, 6 days, you need to look to the next/previous weeks' matching day number, hence the magic 7 number.
On Tue, May 8, 2018 at 3:39 PM, Richard Kaye rkaye@invaluable.com wrote:
Or an ICASE? (I haven't quite wrapped my head around what you're doing there but it seems like there are 3 states?)
m.theOffset=ICASE(theDiff>3, 7-m.theDiff,theDiff<-3, 7+m.theDiff, m.theDiff)
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 3:25 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
Did I mention I like date math? Brain-twisting stuff.
On Tue, May 8, 2018 at 5:14 PM, Ted Roche tedroche@gmail.com wrote:
How about:
FUNCTION olddate(thedate, offset)
- parameters:
- the date: the source date
- offset number of years offset, positive or negative
- returns: the nearest date that is the same day of week as the source date
LOCAL thediff, theoffset thediff = DOW(thedate) - DOW(GOMONTH(thedate, offset*12)) theoffset = IIF(ABS(thediff)>3, 7-SIGN(thediff)*(thediff), thediff) RETURN GOMONTH(thedate, offset*12)+theoffset
ABS() only picks up the high end of the date difference, 4,5,6 SIGN() toggles whether you add or subtract the difference (minus a minus is a plus)
On Tue, May 8, 2018 at 5:03 PM, Ted Roche tedroche@gmail.com wrote:
An ICASE might do it.
Basically the idea is get the day number (DOW) of the current date, like 2 for Tuesday if SET FDOW is 1 ("the first day of the week is Monday")
Then create a new date with GOMONTH() and get the day number of that, some number 1 through 7. So if the new date is a five, I want to go back 3 to get to 2. Similarly, if it's a 6, I want to go forward 3 to get to the next, closest 2.
So, you want to find the nearest matching day number: they're either the same day, so zero offset, or the matching day number are 1,2,3 days earlier or later.
so you take the difference between the original date and the new date. if the absolute difference is 3 or less, that's your offset and you use that to move the new date to the matching day number.
If the difference is -4, -5, -6 or 4, 5, 6 days, you need to look to the next/previous weeks' matching day number, hence the magic 7 number.
On Tue, May 8, 2018 at 3:39 PM, Richard Kaye rkaye@invaluable.com wrote:
Or an ICASE? (I haven't quite wrapped my head around what you're doing there but it seems like there are 3 states?)
m.theOffset=ICASE(theDiff>3, 7-m.theDiff,theDiff<-3, 7+m.theDiff, m.theDiff)
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 3:25 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
I owe you a Scotch next time you're in the area.
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 5:15 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
Did I mention I like date math? Brain-twisting stuff.
On Tue, May 8, 2018 at 5:14 PM, Ted Roche tedroche@gmail.com wrote:
How about:
FUNCTION olddate(thedate, offset)
- parameters:
- the date: the source date
- offset number of years offset, positive or negative
- returns: the nearest date that is the same day of week as the source date
LOCAL thediff, theoffset thediff = DOW(thedate) - DOW(GOMONTH(thedate, offset*12)) theoffset = IIF(ABS(thediff)>3, 7-SIGN(thediff)*(thediff), thediff) RETURN GOMONTH(thedate, offset*12)+theoffset
ABS() only picks up the high end of the date difference, 4,5,6 SIGN() toggles whether you add or subtract the difference (minus a minus is a plus)
On Tue, May 8, 2018 at 5:03 PM, Ted Roche tedroche@gmail.com wrote:
An ICASE might do it.
Basically the idea is get the day number (DOW) of the current date, like 2 for Tuesday if SET FDOW is 1 ("the first day of the week is Monday")
Then create a new date with GOMONTH() and get the day number of that, some number 1 through 7. So if the new date is a five, I want to go back 3 to get to 2. Similarly, if it's a 6, I want to go forward 3 to get to the next, closest 2.
So, you want to find the nearest matching day number: they're either the same day, so zero offset, or the matching day number are 1,2,3 days earlier or later.
so you take the difference between the original date and the new date. if the absolute difference is 3 or less, that's your offset and you use that to move the new date to the matching day number.
If the difference is -4, -5, -6 or 4, 5, 6 days, you need to look to the next/previous weeks' matching day number, hence the magic 7 number.
On Tue, May 8, 2018 at 3:39 PM, Richard Kaye rkaye@invaluable.com wrote:
Or an ICASE? (I haven't quite wrapped my head around what you're doing there but it seems like there are 3 states?)
m.theOffset=ICASE(theDiff>3, 7-m.theDiff,theDiff<-3, 7+m.theDiff, m.theDiff)
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Ted Roche Sent: Tuesday, May 08, 2018 3:25 PM To: profoxtech@leafe.com Subject: Re: Fun with date calculations in VFP
GOMONTH() just moves back to 2/28 on years that don't have a 2/29, so your olddate({^2016-02-29},-2) gives you the previous Tuesday, 2/24/2014.
Hmmm. That's an OBO. It goes back 4 instead of forward 3. I think the nearest date ought to be 2014-03-03
Ah, if thediff = -4, it remains -4. That's a bug. Add the second line below after the first:
m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) m.theOffset=IIF(theDiff<-3, 7+m.theDiff, m.theDiff)
I know there's a better algorithm, likely involving MOD() or CEILING() or FLOOR() but it's escaping me at the moment.
There's 49 combinations of original date = (1,2,3,4,5,6,7) and resultant date = (1,2,3,4,5,6,7) and the offset should come out as {-3,-2,-1,0,1,2,3} , but I'm drawing a blank. Anyone? Beuller?
On Tue, May 8, 2018 at 2:15 PM, Richard Kaye rkaye@invaluable.com wrote:
Ted's solution works just fine. What I didn't test yet is using leap day itself as the starting point. Hmmm.....
Program: datestuff3.prgDate: 05/08/2018 11:09 AM- VFP Version: Visual FoxPro 09.00.0000.7423 for Windows
Notes:
ACTIVATE SCREEN CLEAR ? [Today: ]+CHR(9)+CHR(9) ?? DATE() ?? CHR(9)+CDOW(DATE()) ? [Same day last year: ] ?? olddate(DATE(),-1) ?? CHR(9)+CDOW(olddate(DATE(),-1)) ? [Same day 2 years ago: ] ?? olddate(DATE(),-2) ?? CHR(9)+CDOW(olddate(DATE(),-2)) ? [Same day 3 years ago: ] ?? olddate(DATE(),-3) ?? CHR(9)+CDOW(olddate(DATE(),-3)) ? [Same day 10 years ago: ] ?? olddate(DATE(),-10) ?? [ ]+CDOW(olddate(DATE(),-10)) ? [Yesterday: ]+CHR(9) ?? DATE()-1 ?? CHR(9)+CDOW(DATE()-1) ? [Same day last year: ] ?? olddate(DATE()-1,-1) ?? CHR(9)+CDOW(olddate(DATE()-1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()-1,-2) ?? CHR(9)+CDOW(olddate(DATE()-1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()-1,-3) ?? CHR(9)+CDOW(olddate(DATE()-1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()-1,-10) ?? [ ]+CDOW(olddate(DATE()-1,-10)) ? [Tomorrow: ]+CHR(9) ?? DATE()+1 ?? CHR(9)+CDOW(DATE()+1) ? [Same day last year: ] ?? olddate(DATE()+1,-1) ?? CHR(9)+CDOW(olddate(DATE()+1,-1)) ? [Same day 2 years ago: ] ?? olddate(DATE()+1,-2) ?? CHR(9)+CDOW(olddate(DATE()+1,-2)) ? [Same day 3 years ago: ] ?? olddate(DATE()+1,-3) ?? CHR(9)+CDOW(olddate(DATE()+1,-3)) ? [Same day 10 years ago: ] ?? olddate(DATE()+1,-10) ?? [ ]+CDOW(olddate(DATE()+1,-10))
FUNCTION oldDate(theDate AS Date, offset AS Integer)
- compliments of Ted Roche
- parameters: thedate: date to start from
- offset: number of years offset, positive or negative
- returns: nearest date to the offset that falls on the same day of the week
LOCAL m.theDiff, m.theOffset m.theDiff=DOW(m.theDate)-DOW(GOMONTH(m.theDate, m.offset*12)) m.theOffset=IIF(theDiff>3, 7-m.theDiff, m.theDiff) RETURN GOMONTH(m.theDate, m.offset*12) + m.theOffset
ENDFUNC
--
rk
-----Original Message----- From: ProfoxTech profoxtech-bounces@leafe.com On Behalf Of Gene Wirchenko Sent: Tuesday, May 08, 2018 12:46 PM To: profoxtech@leafe.com Subject: RE: Fun with date calculations in VFP
At 06:27 2018-05-08, Richard Kaye rkaye@invaluable.com wrote:
The latter. And that was the approach I was just working through.
What about the week every few years that you will be disregarding? A year has 52 weeks plus one or two days.[snip]
Sincerely,
Gene Wirchenko
[excessive quoting removed by server]
On Tue, May 8, 2018 at 5:39 PM, Richard Kaye rkaye@invaluable.com wrote:
I owe you a Scotch next time you're in the area.
Deal!
-- Ted Roche & Associates, LLC http://www.tedroche.com
I've started a class for a C# like DateTime static class here: https://github.com/eselje/FoxTypes/blob/master/FT_DATETIME.md
I may steal some of the ideas here to embellish it, but if you have time and want to contribute please clone this repo and submit a pull request when done. It's pretty handy.
Eric
On Wed, May 9, 2018 at 10:39 AM, Ted Roche tedroche@gmail.com wrote:
On Tue, May 8, 2018 at 5:39 PM, Richard Kaye rkaye@invaluable.com wrote:
I owe you a Scotch next time you're in the area.
Deal!
-- Ted Roche & Associates, LLC http://www.tedroche.com
[excessive quoting removed by server]
Hi Eric,
something to add to your currently blank function in your class:
FUNCTION IsLeapYear (iYear) RETURN NOT EMPTY(DATE(iYear,2,29))
wOOdy
-----Ursprüngliche Nachricht----- Von: ProFox profox-bounces@leafe.com Im Auftrag von Eric Selje Gesendet: Dienstag, 15. Mai 2018 22:20 An: ProFox Email List profox@leafe.com Betreff: Re: Fun with date calculations in VFP
I've started a class for a C# like DateTime static class here: https://github.com/eselje/FoxTypes/blob/master/FT_DATETIME.md
Will do!
On Wed, May 16, 2018 at 1:42 AM, Jürgen Wondzinski juergen@wondzinski.de wrote:
Hi Eric,
something to add to your currently blank function in your class:
FUNCTION IsLeapYear (iYear) RETURN NOT EMPTY(DATE(iYear,2,29))
wOOdy
-----Ursprüngliche Nachricht----- Von: ProFox profox-bounces@leafe.com Im Auftrag von Eric Selje Gesendet: Dienstag, 15. Mai 2018 22:20 An: ProFox Email List profox@leafe.com Betreff: Re: Fun with date calculations in VFP
I've started a class for a C# like DateTime static class here: https://github.com/eselje/FoxTypes/blob/master/FT_DATETIME.md
[excessive quoting removed by server]
LastDayOfMonth() or LDOM back in my 8.3 days, was always a popular request:
http://fox.wikis.com/wc.dll?Wiki~FindingTheLastDayOfTheMonth~VB
Updated. Clearly a lot of stuff left to do on this class! I got distracted by "work" but feel free to clone and contribute.
set proc to datetime addi _vfp.addoboject("DateTime", "DateTime") && Now it's always available ? _vfp.DateTime.FirstDayOfMonth() && 05/01/2018 ? _vfp.DateTime.FirstDayOfMonth(gomonth(date(),1) && 06/01/2018 ? _vfp.DateTime.LastDayOfMonth() && 05/31/2018 ? _vfp.DateTime.LastDayOfMonth(2012,2) && 02/29/2012 ? _vfp.DateTime.IsLeapYear(2012) && .t.
Eric
On Wed, May 16, 2018 at 5:02 PM, Ted Roche tedroche@gmail.com wrote:
LastDayOfMonth() or LDOM back in my 8.3 days, was always a popular request:
http://fox.wikis.com/wc.dll?Wiki~FindingTheLastDayOfTheMonth~VB
-- Ted Roche Ted Roche & Associates, LLC http://www.tedroche.com
[excessive quoting removed by server]
Hi Eric
I've taken a look at your DateTime class and, as you say, it's a work in progress. Would you be kind enough to keep us informed of updates?
Many Thanks
Paul Newton
-----Original Message----- From: ProFox [mailto:profox-bounces@leafe.com] On Behalf Of Eric Selje Sent: 16 May 2018 23:29 To: ProFox Email List profox@leafe.com Subject: Re: Fun with date calculations in VFP
Updated. Clearly a lot of stuff left to do on this class! I got distracted by "work" but feel free to clone and contribute.
set proc to datetime addi _vfp.addoboject("DateTime", "DateTime") && Now it's always available ? _vfp.DateTime.FirstDayOfMonth() && 05/01/2018 ? _vfp.DateTime.FirstDayOfMonth(gomonth(date(),1) && 06/01/2018 ? _vfp.DateTime.LastDayOfMonth() && 05/31/2018 ? _vfp.DateTime.LastDayOfMonth(2012,2) && 02/29/2012 ? _vfp.DateTime.IsLeapYear(2012) && .t.
Eric
On Wed, May 16, 2018 at 5:02 PM, Ted Roche tedroche@gmail.com wrote:
LastDayOfMonth() or LDOM back in my 8.3 days, was always a popular request:
http://fox.wikis.com/wc.dll?Wiki~FindingTheLastDayOfTheMonth~VB
-- Ted Roche Ted Roche & Associates, LLC http://www.tedroche.com
[excessive quoting removed by server]
On 2018-05-16 18:02, Ted Roche wrote:
LastDayOfMonth() or LDOM back in my 8.3 days, was always a popular request:
http://fox.wikis.com/wc.dll?Wiki~FindingTheLastDayOfTheMonth~VB
Ed Leafe had shared a ton of date functions for VFP years ago. Here's what I have in my framework from Ed:
FUNCTION FirstDayOfMonth(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - (DAY(tdDate)-1)) ENDFUNC && FirstDayOfMonth
FUNCTION FirstDayOfQuarter(tdDate as Date) as Date LOCAL lcDate as String, lcMonth as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcMonth = SUBSTR(lcDate,5,2) lcYear = LEFT(lcDate,4) DO CASE CASE BETWEEN(VAL(lcMonth),1,3) lcDate = "01/01/" + lcYear CASE BETWEEN(VAL(lcMonth),4,6) lcDate = "04/01/" + lcYear CASE BETWEEN(VAL(lcMonth),7,9) lcDate = "07/01/" + lcYear OTHERWISE && CASE BETWEEN(VAL(lcMonth),10,12) lcDate = "10/01/" + lcYear ENDCASE ldDate = CTOD(lcDate) return ldDate ENDFUNC && FirstDayOfQuarter
FUNCTION LastDayOfQuarter(tdDate as Date) as Date LOCAL lcDate as String, lcMonth as String, lcDay as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcMonth = SUBSTR(lcDate,5,2) lcYear = LEFT(lcDate,4) DO CASE CASE BETWEEN(VAL(lcMonth),1,3) lcDate = "01/31/" + lcYear CASE BETWEEN(VAL(lcMonth),4,6) lcDate = "04/30/" + lcYear CASE BETWEEN(VAL(lcMonth),7,9) lcDate = "07/31/" + lcYear OTHERWISE && CASE BETWEEN(VAL(lcMonth),10,12) lcDate = "10/31/" + lcYear ENDCASE ldDate = CTOD(lcDate) return ldDate ENDFUNC && LastDayOfQuarter
FUNCTION FirstDayOfYear(tdDate as Date) as Date LOCAL lcDate as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcYear = LEFT(lcDate,4) lcDate = "01/01/" + lcYear ldDate = CTOD(lcDate) return ldDate ENDFUNC && FirstDayOfYear
FUNCTION LastDayOfYear(tdDate as Date) as Date LOCAL lcDate as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcYear = LEFT(lcDate,4) lcDate = "12/31/" + lcYear ldDate = CTOD(lcDate) return ldDate ENDFUNC && LastDayOfYear
FUNCTION LastDayOfMonth(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,1) - DAY(GOMONTH(tdDate,1))) ENDFUNC && LastDayOfMonth
FUNCTION FirstDayOfWeek(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - (DOW(tdDate)-1)) ENDFUNC && FirstDayOfWeek
FUNCTION LastDayOfWeek(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate + (7 - DOW(tdDate))) ENDFUNC && LastDayOfWeek
FUNCTION LastMonthDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,-1)) ENDFUNC && LastDayOfWeek
FUNCTION NextMonthDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,1)) ENDFUNC && LastDayOfWeek
FUNCTION JulianDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - DATE(YEAR(tdDate)-1, 12, 31)) ENDFUNC && JulianDate
Lots of spare time today so some hopefully constructive criticism: :)
I would redo some of that code to get away from CTOD() as that will fail depending on SET STRICTDATE and if SET DATE is anything besides MDY.
I have a feeling that your first day of week and last day of week will be incorrect in situations with SET FDOW.
I think PARAMETERS() is also advised against and PCOUNT() is better.
I would also move each function into its own program.
For example FirstDayOfQuarter.prg would be:
LPARAMETERS tdDate
LOCAL lnMonth as Integer, lnYear as Integer, ldDate as Date if PCOUNT()=0 then m.tdDate = date() endif m.lnYear = YEAR(m.tdDate) m.lnMonth = MONTH(m.tdDate) DO CASE CASE BETWEEN(m.lnMonth,1,3) m.ldDate = DATE(m.lnYear, 1, 1) CASE BETWEEN(m.lnMonth,4,6) m.ldDate = DATE(m.lnYear, 4, 1) CASE BETWEEN(m.lnMonth,7,9) m.ldDate = DATE(m.lnYear, 7, 1) OTHERWISE && CASE BETWEEN(m.lnMonth,10,12) m.ldDate = DATE(m.lnYear, 10, 1) ENDCASE return ldDate
Frank.
Frank Cazabon
On 18/05/2018 11:30 AM, mbsoftwaresolutions@mbsoftwaresolutions.com wrote:
On 2018-05-16 18:02, Ted Roche wrote:
LastDayOfMonth() or LDOM back in my 8.3 days, was always a popular request:
http://fox.wikis.com/wc.dll?Wiki~FindingTheLastDayOfTheMonth~VB
Ed Leafe had shared a ton of date functions for VFP years ago. Here's what I have in my framework from Ed:
FUNCTION FirstDayOfMonth(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - (DAY(tdDate)-1)) ENDFUNC && FirstDayOfMonth
FUNCTION FirstDayOfQuarter(tdDate as Date) as Date LOCAL lcDate as String, lcMonth as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcMonth = SUBSTR(lcDate,5,2) lcYear = LEFT(lcDate,4) DO CASE CASE BETWEEN(VAL(lcMonth),1,3) lcDate = "01/01/" + lcYear CASE BETWEEN(VAL(lcMonth),4,6) lcDate = "04/01/" + lcYear CASE BETWEEN(VAL(lcMonth),7,9) lcDate = "07/01/" + lcYear OTHERWISE && CASE BETWEEN(VAL(lcMonth),10,12) lcDate = "10/01/" + lcYear ENDCASE ldDate = CTOD(lcDate) return ldDate ENDFUNC && FirstDayOfQuarter
FUNCTION LastDayOfQuarter(tdDate as Date) as Date LOCAL lcDate as String, lcMonth as String, lcDay as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcMonth = SUBSTR(lcDate,5,2) lcYear = LEFT(lcDate,4) DO CASE CASE BETWEEN(VAL(lcMonth),1,3) lcDate = "01/31/" + lcYear CASE BETWEEN(VAL(lcMonth),4,6) lcDate = "04/30/" + lcYear CASE BETWEEN(VAL(lcMonth),7,9) lcDate = "07/31/" + lcYear OTHERWISE && CASE BETWEEN(VAL(lcMonth),10,12) lcDate = "10/31/" + lcYear ENDCASE ldDate = CTOD(lcDate) return ldDate ENDFUNC && LastDayOfQuarter
FUNCTION FirstDayOfYear(tdDate as Date) as Date LOCAL lcDate as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcYear = LEFT(lcDate,4) lcDate = "01/01/" + lcYear ldDate = CTOD(lcDate) return ldDate ENDFUNC && FirstDayOfYear
FUNCTION LastDayOfYear(tdDate as Date) as Date LOCAL lcDate as String, lcYear as String, ldDate as Date if PARAMETERS()=0 then tdDate = date() endif lcDate = DTOS(tdDate) lcYear = LEFT(lcDate,4) lcDate = "12/31/" + lcYear ldDate = CTOD(lcDate) return ldDate ENDFUNC && LastDayOfYear
FUNCTION LastDayOfMonth(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,1) - DAY(GOMONTH(tdDate,1))) ENDFUNC && LastDayOfMonth
FUNCTION FirstDayOfWeek(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - (DOW(tdDate)-1)) ENDFUNC && FirstDayOfWeek
FUNCTION LastDayOfWeek(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate + (7 - DOW(tdDate))) ENDFUNC && LastDayOfWeek
FUNCTION LastMonthDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,-1)) ENDFUNC && LastDayOfWeek
FUNCTION NextMonthDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (GOMONTH(tdDate,1)) ENDFUNC && LastDayOfWeek
FUNCTION JulianDate(tdDate as Date) as Date if PARAMETERS()=0 then tdDate = date() endif return (tdDate - DATE(YEAR(tdDate)-1, 12, 31)) ENDFUNC && JulianDate
[excessive quoting removed by server]
This FirstDayOfQuarter and siblings is much easier to do:
******************************************* FUNCTION GoQuarter(dDate, cValue) * "L" = (L)ast day of dDate's Quarter * "F" = (F)irst day of dDate's Quarter * "N" = first day of (n)ext dDate's Quarter * "P" = first day of (p)previous dDate's Quarter *******************************************
cValue = EVL(cValue, "F") LOCAL dResult DO CASE CASE cValue = "L" dResult = GOMONTH(dDate,(CEILING(MONTH(dDate)/3)*3)-MONTH(dDate)+1)-DAY(dDate) CASE cValue = "F" dResult = GOMONTH(dDate,(CEILING(MONTH(dDate)/3)*3)-MONTH(dDate)-2)-DAY(dDate)+1 CASE cValue = "N" dResult = GOMONTH(dDate,(CEILING(MONTH(dDate)/3)*3)-MONTH(dDate)+1)-DAY(dDate)+1 CASE cValue = "P" dResult = GOMONTH(dDate,(CEILING(MONTH(dDate)/3)*3)-MONTH(dDate)-5)-DAY(dDate)+1 ENDCASE RETURN dResult
wOOdy
"*´¨) ¸.·´¸.·*´¨) ¸.·*¨) (¸.·´. (¸.·` * .·`.Visual FoxPro: It's magic ! (¸.·``··*
-----Ursprüngliche Nachricht----- Von: ProFox profox-bounces@leafe.com Im Auftrag von Frank Cazabon Gesendet: Freitag, 18. Mai 2018 18:41 An: profox@leafe.com Betreff: Re: Fun with date calculations in VFP
Lots of spare time today so some hopefully constructive criticism: :)
I would redo some of that code to get away from CTOD() as that will fail depending on SET STRICTDATE and if SET DATE is anything besides MDY.
I have a feeling that your first day of week and last day of week will be incorrect in situations with SET FDOW.
I think PARAMETERS() is also advised against and PCOUNT() is better.
I would also move each function into its own program.
For example FirstDayOfQuarter.prg would be:
LPARAMETERS tdDate
LOCAL lnMonth as Integer, lnYear as Integer, ldDate as Date if PCOUNT()=0 then m.tdDate = date() endif m.lnYear = YEAR(m.tdDate) m.lnMonth = MONTH(m.tdDate) DO CASE CASE BETWEEN(m.lnMonth,1,3) m.ldDate = DATE(m.lnYear, 1, 1) CASE BETWEEN(m.lnMonth,4,6) m.ldDate = DATE(m.lnYear, 4, 1) CASE BETWEEN(m.lnMonth,7,9) m.ldDate = DATE(m.lnYear, 7, 1) OTHERWISE && CASE BETWEEN(m.lnMonth,10,12) m.ldDate = DATE(m.lnYear, 10, 1) ENDCASE return ldDate
Frank.
Hi everyone! Yes, I'm the Salty Dog page, and this library is an attempt to replicate what's in C#'s static classes, which are really powerful to have around.
The STRING one is mostly complete but I just got started on the DATETIME and it's definitely a work in progress. To stay on top of it, you can click the "Watch" button on the GitHub page and you'll get notifications whenever a new commit happens (I've done a lot just in the last few days as I've been using this library as I work on another class to validate JWTs in FoxPro.
I really like all the feedback! Another thing you can do is submit an issue on the GitHub page itself (and then get notified when it's handled) or better yet, clone the repo and make some contributions! :)
Eric
On Fri, May 18, 2018 at 1:26 PM, Jürgen Wondzinski juergen@wondzinski.de wrote:
This FirstDayOfQuarter and siblings is much easier to do:
FUNCTION GoQuarter(dDate, cValue)
- "L" = (L)ast day of dDate's Quarter
- "F" = (F)irst day of dDate's Quarter
- "N" = first day of (n)ext dDate's Quarter
- "P" = first day of (p)previous dDate's Quarter
cValue = EVL(cValue, "F") LOCAL dResult DO CASE CASE cValue = "L" dResult = GOMONTH(dDate,(CEILING(MONTH( dDate)/3)*3)-MONTH(dDate)+1)-DAY(dDate) CASE cValue = "F" dResult = GOMONTH(dDate,(CEILING(MONTH( dDate)/3)*3)-MONTH(dDate)-2)-DAY(dDate)+1 CASE cValue = "N" dResult = GOMONTH(dDate,(CEILING(MONTH( dDate)/3)*3)-MONTH(dDate)+1)-DAY(dDate)+1 CASE cValue = "P" dResult = GOMONTH(dDate,(CEILING(MONTH( dDate)/3)*3)-MONTH(dDate)-5)-DAY(dDate)+1 ENDCASE RETURN dResult
wOOdy
"*´¨) ¸.·´¸.·*´¨) ¸.·*¨) (¸.·´. (¸.·` * .·`.Visual FoxPro: It's magic ! (¸.·``··*
-----Ursprüngliche Nachricht----- Von: ProFox profox-bounces@leafe.com Im Auftrag von Frank Cazabon Gesendet: Freitag, 18. Mai 2018 18:41 An: profox@leafe.com Betreff: Re: Fun with date calculations in VFP
Lots of spare time today so some hopefully constructive criticism: :)
I would redo some of that code to get away from CTOD() as that will fail depending on SET STRICTDATE and if SET DATE is anything besides MDY.
I have a feeling that your first day of week and last day of week will be incorrect in situations with SET FDOW.
I think PARAMETERS() is also advised against and PCOUNT() is better.
I would also move each function into its own program.
For example FirstDayOfQuarter.prg would be:
LPARAMETERS tdDate
LOCAL lnMonth as Integer, lnYear as Integer, ldDate as Date if PCOUNT()=0 then m.tdDate = date() endif m.lnYear = YEAR(m.tdDate) m.lnMonth = MONTH(m.tdDate) DO CASE CASE BETWEEN(m.lnMonth,1,3) m.ldDate = DATE(m.lnYear, 1, 1) CASE BETWEEN(m.lnMonth,4,6) m.ldDate = DATE(m.lnYear, 4, 1) CASE BETWEEN(m.lnMonth,7,9) m.ldDate = DATE(m.lnYear, 7, 1) OTHERWISE && CASE BETWEEN(m.lnMonth,10,12) m.ldDate = DATE(m.lnYear, 10, 1) ENDCASE return ldDateFrank.
[excessive quoting removed by server]
You have a set of Add functions: AddYears, AddDays, AddHours, Minutes, Seconds, Ticks... where's AddMonth, besides the obvious GOMONTH()?
Time support native in VFP has always been weak. I wrote a s2hms and hms2s to convert between seconds and HH:MM:SS strings.
DTOT converts a Data to a datetime by setting time to 00:00:00. It would be handy to have the ability to set the time as well, even though it's pretty much the trivial
RETURN DTOT(thedate)+hms2s(thetime)
A pretty print would be handy, I don't know C#, but PHP et all has fprint with a unix-standard-y format string, String.Format does the same in C# apparently:
http://www.csharp-examples.net/string-format-datetime/ https://secure.php.net/manual/en/datetime.format.php
I can't tell you how many times I've written a UDF or inline code to generate variations on "Monday, December 31, 1999 12:34:56 am" - having that in one place would be handy.
On Tue, May 15, 2018 at 4:20 PM, Eric Selje Eric@saltydogllc.com wrote:
I've started a class for a C# like DateTime static class here: https://github.com/eselje/FoxTypes/blob/master/FT_DATETIME.md
I may steal some of the ideas here to embellish it, but if you have time and want to contribute please clone this repo and submit a pull request when done. It's pretty handy.
Eric
On Wed, May 9, 2018 at 10:39 AM, Ted Roche tedroche@gmail.com wrote:
On Tue, May 8, 2018 at 5:39 PM, Richard Kaye rkaye@invaluable.com wrote:
I owe you a Scotch next time you're in the area.
Deal!
-- Ted Roche & Associates, LLC http://www.tedroche.com
[excessive quoting removed by server]
There's a VFP implementation of the C# String.Format() here: http://saltydogllc.com/string-format-for-visual-foxpro/
On Thu, May 17, 2018 at 8:11 AM, Alan Bourke alanpbourke@fastmail.fm wrote:
There's a VFP implementation of the C# String.Format() here: http://saltydogllc.com/string-format-for-visual-foxpro/
Cool! Check that off the list!
Hmmm.. You know that "SaltyDog" is actually Eric's page ?
wOOdy
-----Ursprüngliche Nachricht----- Von: ProFox [mailto:profox-bounces@leafe.com] Im Auftrag von Alan Bourke Gesendet: Donnerstag, 17. Mai 2018 14:12 An: profoxtech@leafe.com Betreff: Re: Fun with date calculations in VFP
There's a VFP implementation of the C# String.Format() here: http://saltydogllc.com/string-format-for-visual-foxpro/