Re: Subtract n months from datetime

2022-06-27 Thread Peter J. Holzer
On 2022-06-21 05:29:52 +0100, Paulo da Silva wrote:
> I implemented a part of a script to subtract n months from datetime.
> Basically I subtracted n%12 from year and n//12 from the month adding 12
> months when it goes<=0. Then used try when converting to datetime again. So,
> if the day is for example 31 for a 30 days month it raises a ValuError
> exception. Then I subtract 1 to day and repeat.

For a recent longish discussion of that matter see the threads starting
at https://mail.python.org/pipermail/python-list/2022-April/905985.html
and https://mail.python.org/pipermail/python-list/2022-April/906045.html
(the latter also contains some prototype code).

(I apologize for not pursuing that further at the time. I wanted to
bolster that case with some real world applications, but I was a bit
swamped with Real Work™ and didn't find anything suitable.)

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Aw: Re: Subtract n months from datetime [Why?]

2022-06-23 Thread Karsten Hilbert
> What makes sense depends on where you're looking from.
>
> It's 28 February, you need to keep it for 5 years, therefore you could
> reason that you can dispose of it on 28 February, 5 years hence.
>
> However, that happens to be a leap year.
>
> Should you still have it on 29 February?

Nope because that's *after* the 5 years (they end Feb 28).

If it originates on March 1st, however, you shouldn't dispose of it on Feb 29th 
just yet.

Karsten
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-22 Thread Paulo da Silva

Às 19:47 de 22/06/22, Marco Sulla escreveu:

The package arrow has a simple shift method for months, weeks etc

https://arrow.readthedocs.io/en/latest/#replace-shift


At first look it seems pretty good! I didn't know it.
Thank you Marco.

Paulo
--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime [Why?]

2022-06-22 Thread Paulo da Silva

Às 20:25 de 22/06/22, Barry Scott escreveu:




On 22 Jun 2022, at 17:59, Paulo da Silva  
wrote:

Às 05:29 de 21/06/22, Paulo da Silva escreveu:

As a general response to some comments ...

Suppose we need to delete records from a database older than ...
Today, it's usual to specify days. For example you have to keep some gov papers 
for 90 days. This seems to come from computers era. In our minds, however, we 
immediately think 90 days=3 months.
For example, one may want to delete some files older than 9 months. It's far 
more intuitive than 270 days.
When we talk about years it is still going. For example I need to keep my 
receipts for 5 years because IRS audits.
Accepting this, it's intuitive, for example, that 3 months before July, 31 is 
April, 30.
The same happens for the years. 5 years before February, 29 is February, 28.


The advantage of 30 days, 90 days etc is that a contract or law does not need 
to tell you
how to deal with the problems of calendar months.

As you say in peoples thoughts that 1 month or 3 months etc. But an accounts 
department
will know how to to the number of days till they have to pay up.

Yes. But my point is to justify why I want months. And it depends on the 
application.
Let's suppose a program for Joe User to clean something - files, for 
example. There are no rules except for the comfort of the user. He would 
prefer to be able to say 9 months back instead of 270 days. And by 9 
months, he expects to count down 9 months. Not 270 days.

That's what happens with the script I am writing.

Paulo
--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime [Why?]

2022-06-22 Thread MRAB

On 2022-06-22 20:25, Barry Scott wrote:




On 22 Jun 2022, at 17:59, Paulo da Silva  
wrote:

Às 05:29 de 21/06/22, Paulo da Silva escreveu:

As a general response to some comments ...

Suppose we need to delete records from a database older than ...
Today, it's usual to specify days. For example you have to keep some gov papers 
for 90 days. This seems to come from computers era. In our minds, however, we 
immediately think 90 days=3 months.
For example, one may want to delete some files older than 9 months. It's far 
more intuitive than 270 days.
When we talk about years it is still going. For example I need to keep my 
receipts for 5 years because IRS audits.
Accepting this, it's intuitive, for example, that 3 months before July, 31 is 
April, 30.
The same happens for the years. 5 years before February, 29 is February, 28.


The advantage of 30 days, 90 days etc is that a contract or law does not need 
to tell you
how to deal with the problems of calendar months.

As you say in peoples thoughts that 1 month or 3 months etc. But an accounts 
department
will know how to to the number of days till they have to pay up.

OT, but in the UK, when the Gregorian Calendar was adopted, there were 
complaints.


It's often believed that they were just being superstitious about 
"losing" 11 days, but the truth is that they were complaining that rent 
was paid by the month, but wages by the number of days worked.


That month was a lot shorter, with far fewer working days, yet they were 
still expected to pay the same rent!

--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime [Why?]

2022-06-22 Thread Barry Scott


> On 22 Jun 2022, at 17:59, Paulo da Silva 
>  wrote:
> 
> Às 05:29 de 21/06/22, Paulo da Silva escreveu:
> 
> As a general response to some comments ...
> 
> Suppose we need to delete records from a database older than ...
> Today, it's usual to specify days. For example you have to keep some gov 
> papers for 90 days. This seems to come from computers era. In our minds, 
> however, we immediately think 90 days=3 months.
> For example, one may want to delete some files older than 9 months. It's far 
> more intuitive than 270 days.
> When we talk about years it is still going. For example I need to keep my 
> receipts for 5 years because IRS audits.
> Accepting this, it's intuitive, for example, that 3 months before July, 31 is 
> April, 30.
> The same happens for the years. 5 years before February, 29 is February, 28.

The advantage of 30 days, 90 days etc is that a contract or law does not need 
to tell you
how to deal with the problems of calendar months.

As you say in peoples thoughts that 1 month or 3 months etc. But an accounts 
department
will know how to to the number of days till they have to pay up.

Barry


> 
> Again, this is my opinion and that's the way I like it :-)
> Regards
> Paulo
> -- 
> https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-22 Thread Marco Sulla
The package arrow has a simple shift method for months, weeks etc

https://arrow.readthedocs.io/en/latest/#replace-shift
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime [Why?]

2022-06-22 Thread MRAB

On 2022-06-22 17:59, Paulo da Silva wrote:

Às 05:29 de 21/06/22, Paulo da Silva escreveu:

As a general response to some comments ...

Suppose we need to delete records from a database older than ...
Today, it's usual to specify days. For example you have to keep some gov
papers for 90 days. This seems to come from computers era. In our minds,
however, we immediately think 90 days=3 months.
For example, one may want to delete some files older than 9 months. It's
far more intuitive than 270 days.
When we talk about years it is still going. For example I need to keep
my receipts for 5 years because IRS audits.
Accepting this, it's intuitive, for example, that 3 months before July,
31 is April, 30.
The same happens for the years. 5 years before February, 29 is February, 28.

Again, this is my opinion and that's the way I like it :-)


What makes sense depends on where you're looking from.

It's 28 February, you need to keep it for 5 years, therefore you could 
reason that you can dispose of it on 28 February, 5 years hence.


However, that happens to be a leap year.

Should you still have it on 29 February?
--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime [Why?]

2022-06-22 Thread Paulo da Silva

Às 05:29 de 21/06/22, Paulo da Silva escreveu:

As a general response to some comments ...

Suppose we need to delete records from a database older than ...
Today, it's usual to specify days. For example you have to keep some gov 
papers for 90 days. This seems to come from computers era. In our minds, 
however, we immediately think 90 days=3 months.
For example, one may want to delete some files older than 9 months. It's 
far more intuitive than 270 days.
When we talk about years it is still going. For example I need to keep 
my receipts for 5 years because IRS audits.
Accepting this, it's intuitive, for example, that 3 months before July, 
31 is April, 30.

The same happens for the years. 5 years before February, 29 is February, 28.

Again, this is my opinion and that's the way I like it :-)
Regards
Paulo
--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-21 Thread Cameron Simpson
On 21Jun2022 17:02, Paulo da Silva  wrote:
>I have a datetime, not a date.

Then you need a date. I would break the datetime into a date and a time, 
then do the months stuff to the date, then compose a new datetime from 
the result.

>Anyway, the use of calendar.monthrange simplifies the task a lot.

Hmm, yes it would.

The important thing to remember about any solutions mentioned is that 
dates and datetimes have different semantics. Specificly, you can't add 
fixed elapsed times such as seconds to do "calendar like" arithmetic, 
which works in days etc because months have varying numbers of days, and 
days have varying numbers of seconds (not merely the odd leap second but 
also the horrors of timezones and summer/winter time shifts).

So working with the calendar component (days upwards) is a meaningful 
thing. But working in, say, seconds with the _bjective_ of doing days or 
months is nearly pointless.

Cheers,
Cameron Simpson 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-21 Thread Paulo da Silva

Às 05:44 de 21/06/22, Paul Bryan escreveu:

Here's how my code does it:


import calendar

def add_months(value: date, n: int):
   """Return a date value with n months added (or subtracted if
negative)."""
   year = value.year + (value.month - 1 + n) // 12
   month = (value.month - 1 + n) % 12 + 1
   day = min(value.day, calendar.monthrange(year, month)[1])
   return date(year, month, day)

Paul

I have a datetime, not a date.
Anyway, the use of calendar.monthrange simplifies the task a lot.

Assuming dtnow has the current datetime and dtn the number of months to 
be subtracted, here is my solution (the code was not cleaned yet - just 
a test):

dtnow_t=list(dtnow.timetuple()[:6]+(dtnow.microsecond,))
y=dtnow_t[0] # y,m,d,*_=dtnow_t seems slower
m=dtnow_t[1]
d=dtnow_t[2]
dy,dm=divmod(dtn,12)
y-=dy
m-=dm
if m<1:
m+=12
y-=1
daysinmonth=calendar.monthrange(y,m)[1]
d=min(d,daysinmonth)
dtnow_t[0]=y
dtnow_t[1]=m
dtnow_t[2]=d
bt=datetime.datetime(*dtnow_t)

Any comments are welcome.

Thank you.
Paulo




On Tue, 2022-06-21 at 05:29 +0100, Paulo da Silva wrote:

Hi!

I implemented a part of a script to subtract n months from datetime.
Basically I subtracted n%12 from year and n//12 from the month adding
12
months when it goes<=0. Then used try when converting to datetime
again.
So, if the day is for example 31 for a 30 days month it raises a
ValuError exception. Then I subtract 1 to day and repeat.

The code seems too naive and very very complicated!
What is the best way to achieve this? Any existent module?

At the very end, what I want is to subtract nx where x can be y, m,
w, d
for respectively years, months, weeks or days.

I feel I am missing something here ...

Thanks.
Paulo





--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-21 Thread Dan Stromberg
On Mon, Jun 20, 2022 at 9:45 PM Paul Bryan  wrote:

> Here's how my code does it:
>
>
> import calendar
>
> def add_months(value: date, n: int):
>   """Return a date value with n months added (or subtracted if
> negative)."""
>   year = value.year + (value.month - 1 + n) // 12
>   month = (value.month - 1 + n) % 12 + 1
>   day = min(value.day, calendar.monthrange(year, month)[1])
>   return date(year, month, day)
>

This looks interesting.

You also could add or subtract the average number of seconds in a month:
2629743.75

This has the strange property that the time of day, or even calendar day,
could change. However, it is round-trippable.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-21 Thread Richard Damon

On 6/21/22 12:29 AM, Paulo da Silva wrote:

Hi!

I implemented a part of a script to subtract n months from datetime.
Basically I subtracted n%12 from year and n//12 from the month adding 
12 months when it goes<=0. Then used try when converting to datetime 
again. So, if the day is for example 31 for a 30 days month it raises 
a ValuError exception. Then I subtract 1 to day and repeat.


The code seems too naive and very very complicated!
What is the best way to achieve this? Any existent module?

At the very end, what I want is to subtract nx where x can be y, m, w, 
d for respectively years, months, weeks or days.


I feel I am missing something here ...

Thanks.
Paulo

The biggest issue with "subtracting months" is getting the right 
definition of what you mean by that, especially in the corner cases, 
once that is established, programming it is fairly easy.


The problem is that a month isn't a fixed unit of time, but is a period 
anywhere from 28 to 31 days. (you get the same problem for years, but 
the difference is more special case, the presence or absent of Feb 29th.)


The normal definition of this operation has the strange property that if 
you subtract a month, then add a month, you sometimes don't get back to 
the same day as you started with. Also subtracting one month, and then 
subtracting another month might get you a different day than subtracting 
2 months at once (Think of Mar 31st).


In short, this sort of date operation IS hard, and application specific, 
so while there may be pre-built modules that have this operation, you 
need to see if it uses a compatible definition of what you want.


One alternative, which breaks other expectations, is to think of a month 
as 30 or 30.5 (so 2 months are 61 days) days, and add that. It says that 
often a month later than a given day isn't the same day of the month, 
but does make some operations less surprising. (This is hard to do to a 
date expressed as year-month-day, but trivial in some other formats like 
a timestamp.)


--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list


Re: Subtract n months from datetime

2022-06-20 Thread Paul Bryan
Here's how my code does it:


import calendar

def add_months(value: date, n: int):
  """Return a date value with n months added (or subtracted if
negative)."""
  year = value.year + (value.month - 1 + n) // 12
  month = (value.month - 1 + n) % 12 + 1
  day = min(value.day, calendar.monthrange(year, month)[1])
  return date(year, month, day)

Paul

On Tue, 2022-06-21 at 05:29 +0100, Paulo da Silva wrote:
> Hi!
> 
> I implemented a part of a script to subtract n months from datetime.
> Basically I subtracted n%12 from year and n//12 from the month adding
> 12 
> months when it goes<=0. Then used try when converting to datetime
> again. 
> So, if the day is for example 31 for a 30 days month it raises a 
> ValuError exception. Then I subtract 1 to day and repeat.
> 
> The code seems too naive and very very complicated!
> What is the best way to achieve this? Any existent module?
> 
> At the very end, what I want is to subtract nx where x can be y, m,
> w, d 
> for respectively years, months, weeks or days.
> 
> I feel I am missing something here ...
> 
> Thanks.
> Paulo
> 

-- 
https://mail.python.org/mailman/listinfo/python-list