Cara menggunakan datetime python

Saya menggunakan modul Python datetime. Saya mencari untuk menghitung tanggal 6 bulan dari tanggal saat ini. Bisakah seseorang memberi saya sedikit bantuan untuk melakukan ini?

Alasan saya ingin membuat tanggal 6 bulan dari tanggal saat ini adalah untuk menghasilkan tanggal ulasan. Jika pengguna memasukkan data ke dalam sistem, ia akan memiliki tanggal peninjauan 6 bulan sejak tanggal mereka memasukkan data.

import datetime
print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat()

Saya menemukan solusi ini bagus. (Ini menggunakan ekstensi python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

Keuntungan dari pendekatan ini adalah bahwa ia menangani masalah dengan 28, 30, 31 hari dll. Ini menjadi sangat berguna dalam menangani aturan dan skenario bisnis (katakanlah pembuatan faktur dll.)

$ date(2010,12,31)+relativedelta(months=+1)
  datetime.date(2011, 1, 31)

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)

Yah, itu tergantung apa yang Anda maksud dengan 6 bulan dari tanggal saat ini.

  1. Menggunakan bulan alami:

    (day, month, year) = (day, (month+6)%12, year+(month+6)/12)
    
  2. Menggunakan definisi bankir, 6 * 30:

    date += datetime.timedelta(6*30)
    

Untuk perhitungan awal bulan ke bulan:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)

Apa yang kamu maksud dengan '6 bulan'. Apakah 2009-02-13 + 6 bulan == 2009-08-13 atau 2009-02-13 + 6 * 30 hari?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'

Info lebih lanjut tentang mx.DateTime

Jadi, berikut adalah contoh dari dateutil.relativedelta yang menurut saya berguna untuk iterasi sepanjang tahun lalu, melewatkan satu bulan setiap kali hingga tanggal sekarang:

>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.datetime.today()
>>> month_count = 0
>>> while month_count < 12:
...  day = today - relativedelta(months=month_count)
...  print day
...  month_count += 1
... 
2010-07-07 10:51:45.187968
2010-06-07 10:51:45.187968
2010-05-07 10:51:45.187968
2010-04-07 10:51:45.187968
2010-03-07 10:51:45.187968
2010-02-07 10:51:45.187968
2010-01-07 10:51:45.187968
2009-12-07 10:51:45.187968
2009-11-07 10:51:45.187968
2009-10-07 10:51:45.187968
2009-09-07 10:51:45.187968
2009-08-07 10:51:45.187968

Seperti jawaban lain, Anda harus mencari tahu apa yang sebenarnya Anda maksud dengan "6 bulan dari sekarang." Jika Anda maksudkan "hari ini di bulan dalam enam bulan di masa depan" maka ini akan berlaku:

datetime.datetime.now() + relativedelta(months=6)

Dengan Python 3.x Anda dapat melakukannya seperti ini:

from datetime import datetime, timedelta
from dateutil.relativedelta import *

date = datetime.now()
print(date)
# 2018-09-24 13:24:04.007620

date = date + relativedelta(months=+6)
print(date)
# 2019-03-24 13:24:04.007620

tetapi Anda harus menginstal python-dateutil modul:

pip install python-dateutil

Solusi ini berfungsi dengan benar untuk bulan Desember, yang sebagian besar jawabannya di halaman ini tidak. Anda harus terlebih dahulu menggeser bulan dari basis 1 (yaitu Jan = 1) ke basis 0 (yaitu Jan = 0) sebelum menggunakan modulus (%) atau pembagian integer (//), jika tidak November (11) ditambah 1 bulan memberi Anda 12 , yang ketika menemukan sisanya (12% 12) memberikan 0.

(Dan jangan menyarankan "(bulan% 12) + 1" atau Oktober + 1 = Desember!)

def AddMonths(d,x):
    newmonth = ((( d.month - 1) + x ) % 12 ) + 1
    newyear  = d.year + ((( d.month - 1) + x ) / 12 ) 
    return datetime.date( newyear, newmonth, d.day)

Namun ... Ini tidak memperhitungkan masalah seperti 31 Januari + satu bulan. Jadi kami kembali ke OP - apa maksud Anda dengan menambahkan satu bulan? Satu soln adalah untuk mundur sampai Anda mendapatkan hari yang valid, mengingat bahwa kebanyakan orang akan menganggap hari terakhir bulan Januari, ditambah satu bulan, sama dengan hari terakhir bulan Februari. Ini juga akan bekerja pada angka negatif bulan juga. Bukti:

>>> import datetime
>>> AddMonths(datetime.datetime(2010,8,25),1)
datetime.date(2010, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),4)
datetime.date(2010, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),5)
datetime.date(2011, 1, 25)
>>> AddMonths(datetime.datetime(2010,8,25),13)
datetime.date(2011, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),24)
datetime.date(2012, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-1)
datetime.date(2010, 7, 25)
>>> AddMonths(datetime.datetime(2010,8,25),0)
datetime.date(2010, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-12)
datetime.date(2009, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-8)
datetime.date(2009, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-7)
datetime.date(2010, 1, 25)>>> 

Saya tahu ini selama 6 bulan, namun jawabannya menunjukkan di google untuk "menambahkan bulan dengan python" jika Anda menambahkan satu bulan:

import calendar

date = datetime.date.today()    //Or your date

datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])

ini akan menghitung hari dalam bulan ini dan menambahkannya ke tanggal saat ini, menggunakan 365/12 akan 1/12 tahun akan menyebabkan masalah untuk bulan pendek/panjang jika Anda mengulangi tanggal.

Tidak ada cara langsung untuk melakukannya dengan dat Python.

Lihat jenis relativedelta di python-dateutil . Ini memungkinkan Anda untuk menentukan delta waktu dalam bulan.

Cukup gunakan metode timetuple untuk mengekstrak bulan, tambahkan bulan Anda dan buat objek tanggal baru. Jika ada metode yang sudah ada untuk ini, saya tidak tahu itu.

import datetime

def in_the_future(months=1):
    year, month, day = datetime.date.today().timetuple()[:3]
    new_month = month + months
    return datetime.date(year + (new_month / 12), (new_month % 12) or 12, day)

API agak canggung, tetapi berfungsi sebagai contoh. Jelas juga tidak akan bekerja pada kasus sudut seperti 2008-01-31 + 1 bulan. :)

Paket Dateutil memiliki implementasi fungsi seperti itu. Namun perlu diperhatikan, bahwa ini akan menjadi naif , seperti yang telah ditunjukkan orang lain.

Menggunakan pustaka standar Python, mis. Tanpa dateutil atau lainnya, dan menyelesaikan masalah '31 Februari':

import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

Pengujian:

>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))

Saya memiliki cara yang lebih baik untuk menyelesaikan masalah '31 Februari':

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)

Saya pikir itu juga berfungsi dengan angka negatif (untuk mengurangi bulan), tetapi saya belum banyak menguji ini.

Bagaimana dengan ini? Tidak menggunakan perpustakaan lain (dateutil) atau timedelta? membangun di atas vartec jawaban saya melakukan ini dan saya yakin itu berhasil:

import datetime

today = datetime.date.today()
six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)

Saya mencoba menggunakan timedelta, tetapi karena menghitung hari, 365/2 atau 6*356/12 tidak selalu diterjemahkan menjadi 6 bulan, melainkan 182 hari. misalnya.

day = datetime.date(2015, 3, 10)
print day
>>> 2015-03-10

print (day + datetime.timedelta(6*365/12))
>>> 2015-09-08

Saya percaya bahwa kami biasanya berasumsi bahwa 6 bulan dari hari tertentu akan mendarat pada hari yang sama dalam sebulan tetapi 6 bulan kemudian (mis. 2015-03-10 -> 2015-09-10, Bukan 2015-09-08)

Saya harap kamu terbantu dengan hal ini.

Kelas QDate dari PyQt4 memiliki fungsi addmonths.

>>>from PyQt4.QtCore import QDate  
>>>dt = QDate(2009,12,31)  
>>>required = dt.addMonths(6) 

>>>required
PyQt4.QtCore.QDate(2010, 6, 30)

>>>required.toPyDate()
datetime.date(2010, 6, 30)

import time

def add_month(start_time, months):  

        ret = time.strptime(start_time, '%Y-%m-%d')
        t = list(ret)

        t[1] += months

        if t[1] > 12:
            t[0] += 1 + int(months / 12)

            t[1] %= 12

        return int(time.mktime(Tuple(t)))

Memodifikasi AddMonths () untuk digunakan di Zope dan menangani nomor hari yang tidak valid:

def AddMonths(d,x):
    days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
    newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
    if d.day() > days_of_month[newmonth-1]:
      newday = days_of_month[newmonth-1]
    else:
      newday = d.day() 
    return DateTime( newyear, newmonth, newday)

Berikut adalah contoh yang memungkinkan pengguna untuk memutuskan bagaimana mengembalikan tanggal di mana hari lebih besar dari jumlah hari dalam sebulan.

def add_months(date, months, endOfMonthBehaviour='RoundUp'):
    assert endOfMonthBehaviour in ['RoundDown', 'RoundIn', 'RoundOut', 'RoundUp'], \
        'Unknown end of month behaviour'
    year = date.year + (date.month + months - 1) / 12
    month = (date.month + months - 1) % 12 + 1
    day = date.day
    last = monthrange(year, month)[1]
    if day > last:
        if endOfMonthBehaviour == 'RoundDown' or \
            endOfMonthBehaviour == 'RoundOut' and months < 0 or \
            endOfMonthBehaviour == 'RoundIn' and months > 0:
            day = last
        Elif endOfMonthBehaviour == 'RoundUp' or \
            endOfMonthBehaviour == 'RoundOut' and months > 0 or \
            endOfMonthBehaviour == 'RoundIn' and months < 0:
            # we don't need to worry about incrementing the year
            # because there will never be a day in December > 31
            month += 1
            day = 1
    return datetime.date(year, month, day)


>>> from calendar import monthrange
>>> import datetime
>>> add_months(datetime.datetime(2016, 1, 31), 1)
datetime.date(2016, 3, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2)
datetime.date(2015, 12, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
datetime.date(2015, 11, 30)

mengingat bahwa variabel datetime Anda disebut tanggal:

date=datetime.datetime(year=date.year+int((date.month+6)/12),
                       month=(date.month+6)%13 + (1 if (date.month + 
                       months>12) else 0), day=date.day)

Dimodifikasi jawaban Johannes Wei dalam kasus 1new_month = 121. Ini berfungsi dengan baik untuk saya. Bulan-bulan bisa positif atau negatif.

def addMonth(d,months=1):
    year, month, day = d.timetuple()[:3]
    new_month = month + months
    return datetime.date(year + ((new_month-1) / 12), (new_month-1) % 12 +1, day)

Fungsi umum untuk mendapatkan tanggal berikutnya setelah/sebelum x bulan.

 dari tanggal impor waktu datanya. )/12) 
 Mm = int ((diberikan_date.year * 12 + given_date.month) + bulan)% 12) 
 
 Jika mm == 0: 
 yyyy - = 1 
 mm = 12 
 mengembalikan diberikan_date.replace (tahun = yyyy, bulan = mm) 
 
 
 jika __= = "__main __": 
 hari ini = date.today () 
 cetak (hari ini) 
 
 untuk mm dalam [-12, -1, 0, 1, 2, 12, 20]: 
 Next_date = after_month (hari ini, mm) 
 Cetak (next_date) 

Dari jawaban ini , lihat parsedatetime . Contoh kode berikut. Lebih detail: ji unit dengan banyak bahasa alami -> contoh konversi YYYY-MM-DD , dan nyata tantangan/bug konversi parsedatetime .

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, calendar
from datetime import date

# from https://github.com/bear/parsedatetime
import parsedatetime as pdt

def print_todays_date():
    todays_day_of_week = calendar.day_name[date.today().weekday()]
    print "today's date = " + todays_day_of_week + ', ' + \
                              time.strftime('%Y-%m-%d')

def convert_date(natural_language_date):
    cal = pdt.Calendar()
    (struct_time_date, success) = cal.parse(natural_language_date)
    if success:
        formal_date = time.strftime('%Y-%m-%d', struct_time_date)
    else:
        formal_date = '(conversion failed)'
    print '{0:12s} -> {1:10s}'.format(natural_language_date, formal_date)

print_todays_date()
convert_date('6 months')

Kode di atas menghasilkan yang berikut dari mesin MacOSX:

$ ./parsedatetime_simple.py 
today's date = Wednesday, 2015-05-13
6 months     -> 2015-11-13
$ 

Namun solusi lain - harap seseorang akan menyukainya:

def add_months(d, months):
    return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)

Solusi ini tidak berfungsi selama 29,30,31 hari untuk semua kasus, jadi diperlukan solusi yang lebih kuat (yang tidak lagi menyenangkan :)):

def add_months(d, months):
    for i in range(4):
        day = d.day - i
        try:
            return d.replace(day=day).replace(year=d.year+int(months)//12).replace(month=(d.month+int(months))%12)
        except:
            pass
    raise Exception("should not happen")

import datetime


'''
Created on 2011-03-09

@author: tonydiep
'''

def add_business_months(start_date, months_to_add):
    """
    Add months in the way business people think of months. 
    Jan 31, 2011 + 1 month = Feb 28, 2011 to business people
    Method: Add the number of months, roll back the date until it becomes a valid date
    """
    # determine year
    years_change = months_to_add / 12

    # determine if there is carryover from adding months
    if (start_date.month + (months_to_add % 12) > 12 ):
        years_change = years_change + 1

    new_year = start_date.year + years_change

    # determine month
    work = months_to_add % 12
    if 0 == work:
        new_month = start_date.month
    else:
        new_month = (start_date.month + (work % 12)) % 12

    if 0 == new_month:
        new_month = 12 

    # determine day of the month
    new_day = start_date.day
    if(new_day in [31, 30, 29, 28]):
        #user means end of the month
        new_day = 31


    new_date = None
    while (None == new_date and 27 < new_day):
        try:
            new_date = start_date.replace(year=new_year, month=new_month, day=new_day)
        except:
            new_day = new_day - 1   #wind down until we get to a valid date

    return new_date


if __== '__main__':
    #tests
    dates = [datetime.date(2011, 1, 31),
             datetime.date(2011, 2, 28),
             datetime.date(2011, 3, 28),
             datetime.date(2011, 4, 28),
             datetime.date(2011, 5, 28),
             datetime.date(2011, 6, 28),
             datetime.date(2011, 7, 28),
             datetime.date(2011, 8, 28),
             datetime.date(2011, 9, 28),
             datetime.date(2011, 10, 28),
             datetime.date(2011, 11, 28),
             datetime.date(2011, 12, 28),
             ]
    months = range(1, 24)
    for start_date in dates:
        for m in months:
            end_date = add_business_months(start_date, m)
            print("%s\t%s\t%s" %(start_date, end_date, m))

Saya memecahkan masalah ini seperti ini:

import calendar
from datetime import datetime
moths2add = 6
now = datetime.now()
current_year = now.year
current_month = now.month
#count days in months you want to add using calendar module
days = sum(
  [calendar.monthrange(current_year, elem)[1] for elem in range(current_month, current_month + moths)]
    )
print now + days

Gunakan modul datthon python untuk menambahkan timedelta enam bulan ke datetime.today ().

http://docs.python.org/library/datetime.html

Anda tentu saja harus menyelesaikan masalah yang diangkat oleh Johannes Weiß-- apa lakukan yang Anda maksud dengan 6 bulan?

Inilah yang saya pikirkan. Memindahkan jumlah bulan dan tahun yang benar tetapi mengabaikan hari (yang saya butuhkan dalam situasi saya).

import datetime

month_dt = 4
today = datetime.date.today()
y,m = today.year, today.month
m += month_dt-1
year_dt = m//12
new_month = m%12
new_date = datetime.date(y+year_dt, new_month+1, 1)

Saya menggunakan fungsi ini untuk mengubah tahun dan bulan tetapi pertahankan hari:

def replace_month_year(date1, year2, month2):
    try:
        date2 = date1.replace(month = month2, year = year2)
    except:
        date2 = datetime.date(year2, month2 + 1, 1) - datetime.timedelta(days=1)
    return date2

Anda harus menulis:

new_year = my_date.year + (my_date.month + 6) / 12
new_month = (my_date.month + 6) % 12
new_date = replace_month_year(my_date, new_year, new_month)

Ulang jawaban sebelumnya oleh user417751. Mungkin tidak terlalu Pythonic, tetapi membutuhkan panjang bulan dan tahun kabisat yang berbeda. Dalam hal ini 31 Januari 2012 + 1 bulan = 29 Februari 2012.

import datetime
import calendar

def add_mths(d, x):
    newday = d.day
    newmonth = (((d.month - 1) + x) % 12) + 1
    newyear  = d.year + (((d.month - 1) + x) // 12)
    if newday > calendar.mdays[newmonth]:
        newday = calendar.mdays[newmonth]
        if newyear % 4 == 0 and newmonth == 2:
            newday += 1
    return datetime.date(newyear, newmonth, newday)

Saya menggunakan metode replace() dan menulis fungsi rekursif ini. dt adalah objek datetime.datetime:

def month_timedelta(dt, m):
    y = m // 12
    dm = m % 12
    if y == 0:
        if dt.month + m <= 12:
            return dt.replace(month = dt.month + m)
        else:
            dy = (dt.month + m) // 12
            ndt = dt.replace(year=dt.year + dy)
            return ndt.replace(month=(ndt.month + m) % 12)
    else:
        return month_timedelta(dt.replace(year=dt.year + y),dm)

Saya berdentang terlambat, tapi

lihat modul Ken Reitz Maya,

https://github.com/kennethreitz/maya

sesuatu seperti ini dapat membantu Anda, ubah saja jam = 1 ke hari = 1 atau tahun = 1

>>> from maya import MayaInterval

# Create an event that is one hour long, starting now.
>>> event_start = maya.now()
>>> event_end = event_start.add(hours=1)

>>> event = MayaInterval(start=event_start, end=event_end)

Solusi lain: hitung jumlah hari dalam sebulan untuk bulan berikutnya dan tambahkan hasilnya ke tanggal saat ini.

import calendar
import datetime

def date_from_now(months):
    today = datetime.datetime.today()

    month = today.month
    year = today.year
    sum_days = 0

    for i in range(int(months)):
        month += 1

        if month == 13:
            month = 1
            year += 1

        sum_days += calendar.monthrange(year, month)[1]

    return datetime.date.today() + datetime.timedelta(sum_days)

print(date_from_now(12)) # if to day is 2017-01-01, output: 2019-01-01 

Saya pikir akan lebih aman untuk melakukan hal seperti ini daripada menambahkan hari secara manual:

import datetime
today = datetime.date.today()

def addMonths(dt, months = 0):
    new_month = months + dt.month
    year_inc = 0
    if new_month>12:
        year_inc +=1
        new_month -=12
    return dt.replace(month = new_month, year = dt.year+year_inc)

newdate = addMonths(today, 6)