Вы можете написать функцию jQuery, подобную этой, чтобы определить, находится ли элемент в окне просмотра.
Включить это где-то после включения jQuery:
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
Пример использования:
$(window).on('resize scroll', function() {
if ($('#Something').isInViewport()) {
// do something
} else {
// do something else
}
});
Обратите внимание, что это проверяет только верхнее и нижнее положения элементов, оно не проверяет, находится ли элемент вне области просмотра по горизонтали.
import datetime
print (datetime.date.today() + datetime.timedelta(6*365/12)).isoformat()
Ну, это зависит от того, что вы имеете в виду на 6 месяцев с текущей даты.
(day, month, year) = (day, (month+6)%12, year+(month+6)/12)
date += datetime.timedelta(6*30)
(day, month, year) = (day, (month+6)%12, year+(month+6)/12)
может ошибочно, поскольку оно генерирует недопустимые даты, такие как (31, 8, 2015)
- & gt; (31, 2, 2016)
– ohw
17 January 2016 в 00:40
Для начала расчета месяца к месяцу:
from datetime import timedelta
from dateutil.relativedelta import relativedelta
end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
Я нашел это решение хорошим. (Это использует расширение python-dateutil )
from datetime import date
from dateutil.relativedelta import relativedelta
six_months = date.today() + relativedelta(months=+6)
Преимущество такого подхода состоит в том, что он заботится о проблемах с 28, 30, 31 днями и т. Д. Это становится очень полезно при обработке бизнес-правил и сценариев (например, генерация счета и т. д.)
$ date(2010,12,31)+relativedelta(months=+1)
datetime.date(2011, 1, 31)
$ date(2010,12,31)+relativedelta(months=+2)
datetime.date(2011, 2, 28)
Изменен ответ Йоханнеса Вэй в случае 1new_month = 121. Это отлично работает для меня. Месяцы могут быть положительными или отрицательными.
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)
Нет прямого способа сделать это с дат-временем Python.
Проверьте тип relativedelta на python-dateutil . Это позволяет вам указывать временную дельта в месяцах.
Я решил эту проблему следующим образом:
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
, учитывая, что ваша переменная datetime называется date:
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)
Вот пример, который позволяет пользователю решить, как вернуть дату, когда день больше числа дней в месяце.
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)
У меня есть лучший способ решить проблему «31-го сентября»:
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)
Я думаю, что он также работает с отрицательными числами (чтобы вычесть месяцы), но я не тестировал это много.
Из этот ответ , см. parsedatetime . Пример кода. Более подробная информация: модульный тест со многими примерами преобразования на естественном языке -> YYYY-MM-DD и очевидными проблемами / ошибками преобразования парседата времени .
#!/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')
Вышеприведенный код генерирует следующее из машины MacOSX:
$ ./parsedatetime_simple.py
today's date = Wednesday, 2015-05-13
6 months -> 2015-11-13
$
day + datetime.timedelta(6*365/12)
не будет работать всегда, так как несколько лет имеют 365 дней, а другие - 366 дней.
– 3kstc
8 January 2018 в 08:12
Итак, вот пример dateutil.relativedelta
, который я нашел полезным для итерации в прошлом году, пропуская месяц каждый раз до текущей даты:
>>> 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
Как и в случае с другими ответами , вам нужно выяснить, что вы на самом деле имеете в виду «через 6 месяцев». Если вы имеете в виду «сегодняшний день месяца в месяце шесть лет в будущем», тогда это будет делать:
datetime.datetime.now() + relativedelta(months=6)
Я думаю, что было бы безопаснее делать что-то вроде этого вместо того, чтобы вручную добавлять дни:
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)
Использование стандартных библиотек Python, т. е. без dateutil
или других, и решение проблемы «31-го сентября»:
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
Тестирование:
>>>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))
Используйте модуль datetime для python, чтобы добавить timedelta из шести месяцев в datetime.today ().
http://docs.python.org/library/datetime.html
Вы, конечно, должны решить вопрос, поднятый Йоханнесом Вейсом - что делать вы имеете в виду на 6 месяцев?
Я использую эту функцию для изменения года и месяца, но сохраняю день:
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
Вы должны написать:
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)
Выполнение более раннего ответа пользователя417751. Возможно, это не так пифонично, но он заботится о разных месяцах и високосных годах. В этом случае 31 января 2012 года + 1 месяц = 29 февраля 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)
Что вы подразумеваете под «6 месяцев». 2009-02-13 + 6 месяцев == 2009-08-13 или это 2009-02-13 + 6 * 30 дней?
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'
Подробнее о mx.DateTime
Изменен AddMonths () для использования в Zope и обработки недопустимых чисел дня:
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)
Это то, что я придумал. Он перемещает правильное количество месяцев и лет, но игнорирует дни (это было то, что мне нужно в моей ситуации).
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)
Я знаю, что это было в течение 6 месяцев, однако ответ показывает в Google, что «добавление месяцев в python», если вы добавляете один месяц:
import calendar
date = datetime.date.today() //Or your date
datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
, это будет считать дни в текущем месяце и добавьте их к текущей дате, используя 365/12, объявление 1/12 года может вызвать проблемы в течение коротких / длинных месяцев, если вы повторяете дату.
Это решение работает правильно в декабре, что большинство ответов на этой странице нет. Сначала вам нужно сменить месяцы с базы 1 (т.е. Jan = 1) на базу 0 (т.е. Jan = 0) до использования модуля (%) или целочисленного деления (//), в противном случае ноябрь (11) плюс 1 месяц даст вам 12 , который при нахождении остатка (12% 12) дает 0.
(И не предлагайте «(месяц% 12) + 1» или Oct + 1 = декабрь!) [/ g1]
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)
Однако ... Это не учитывает проблему, например, 31 января + один месяц. Итак, мы возвращаемся к OP - что вы подразумеваете, добавив месяц? Один soln должен отступить, пока вы не вернетесь на действительный день, учитывая, что большинство людей предпочтут последний день jan, плюс один месяц, равный последнему дню февраля. Это будет работать и в отрицательном числе месяцев. Доказательство:
>>> 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)>>>
Общая функция для получения следующей даты после / до х месяцев.
from datetime import date def after_month(given_date, month): yyyy = int(((given_date.year * 12 + given_date.month) + month)/12) mm = int(((given_date.year * 12 + given_date.month) + month)%12) if mm == 0: yyyy -= 1 mm = 12 return given_date.replace(year=yyyy, month=mm) if __name__ == "__main__": today = date.today() print(today) for mm in [-12, -1, 0, 1, 2, 12, 20 ]: next_date = after_month(today, mm) print(next_date)
Просто используйте метод timetuple , чтобы извлечь месяцы, добавить свои месяцы и создать новый объект даты. Если для этого уже существует существующий метод, я этого не знаю.
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, day)
API немного неуклюжий, но работает в качестве примера. Также, очевидно, не будет работать в таких угловых случаях, как 2008-01-31 + 1 месяц. :) [/ Д2]
new_month % 12
должна быть (new_month % 12) or 12
. В противном случае, если вы попробуете это в ноябре, вы получите сообщение об ошибке. :)
– Jordan Reiter
2 May 2011 в 22:45
Еще одно решение - надеюсь, кому-то это понравится:
def add_months(d, months):
return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)
Это решение не работает в течение дней 29,30,31 для всех случаев, поэтому требуется более надежное решение (что не так приятно больше :)):
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 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)))
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 __name__ == '__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))
Класс QDate PyQt4 имеет функцию 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)
В пакете Dateutil реализована такая функциональность. Но имейте в виду, что это будет наивным , как уже указывали другие.
Как насчет этого? Не использовать другую библиотеку (dateutil
) или timedelta
? на основе ответа vartec Я сделал это, и я считаю, что он работает:
import datetime
today = datetime.date.today()
six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)
Я попытался использовать timedelta
, но поскольку он подсчитывает дни, 365/2
или 6*356/12
не всегда переводится на 6 месяцев, а на 182 дня. например,
day = datetime.date(2015, 3, 10)
print day
>>> 2015-03-10
print (day + datetime.timedelta(6*365/12))
>>> 2015-09-08
Я считаю, что мы обычно предполагаем, что 6 месяцев с определенного дня приземляются в тот же день месяца, но через 6 месяцев (т.е. 2015-03-10
-> 2015-09-10
, Not 2015-09-08
)
Надеюсь, вы найдете это полезным.
day + datetime.timedelta(6*365/12)
не будет работать всегда, так как несколько лет имеют 365 дней, а другие - 366 дней.
– 3kstc
8 January 2018 в 08:12
dateutil.relativedelta
, прежде чем сдаться и решить этот ответ. – Daniel F 4 August 2015 в 22:28