Что стандартный путь состоит в том, чтобы добавить секунды N к datetime.time в Python?

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

333
задан Community 23 May 2017 в 01:47
поделиться

6 ответов

Можно использовать полный datetime переменные с timedelta, и путем обеспечения фиктивной даты затем с помощью time, чтобы просто получить временную стоимость.

, Например:

import datetime
a = datetime.datetime(100,1,1,11,34,59)
b = a + datetime.timedelta(0,3) # days, seconds, then other fields.
print a.time()
print b.time()

результаты в двух значениях, на расстоянии в три секунды:

11:34:59
11:35:02

Вы могли также выбрать более читаемое

b = a + datetime.timedelta(seconds=3)

, если Вы так склонны.

<час>

, Если Вы после функции, которая может сделать это, можно изучить использование addSecs ниже:

import datetime

def addSecs(tm, secs):
    fulldate = datetime.datetime(100, 1, 1, tm.hour, tm.minute, tm.second)
    fulldate = fulldate + datetime.timedelta(seconds=secs)
    return fulldate.time()

a = datetime.datetime.now().time()
b = addSecs(a, 300)
print a
print b

Это производит:

 09:11:55.775695
 09:16:55
463
ответ дан paxdiablo 23 November 2019 в 00:43
поделиться

Как другие здесь заявили, можно просто использовать полные объекты даты и времени повсюду:

sometime = get_some_time() # the time to which you want to add 3 seconds
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()

Однако я думаю, что стоит объяснить, почему требуются полные объекты даты и времени. Рассмотрите то, что произошло бы, если бы я добавил 2 часа к 23:00. Каково корректное поведение? Исключение, потому что у Вас не может быть времени, больше, чем 23:59? Это должно повториться назад?

Различные программисты будут ожидать разные вещи, поэтому какой бы ни результат, который они выбрали, удивит много людей. Хуже все же, программисты записали бы код, который работал просто великолепно, когда они протестировали его первоначально, и затем имейте его, повреждаются позже путем выполнения чего-то неожиданного. Это очень плохо, который является, почему Нельзя добавить, что timedelta возражает против объектов времени.

48
ответ дан Eli Courtwright 23 November 2019 в 00:43
поделиться

Одна небольшая вещь, могла бы добавить ясность для переопределения значения по умолчанию в течение многих секунд

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)
19
ответ дан unmounted 23 November 2019 в 00:43
поделиться

Благодаря @Pax Diablo, @bvmou и @Arachnid для предложения использования полного datetimes повсюду. Если я должен принять объекты datetime.time из внешнего источника, то это, кажется, альтернатива add_secs_to_time() функция:

def add_secs_to_time(timeval, secs_to_add):
    dummy_date = datetime.date(1, 1, 1)
    full_datetime = datetime.datetime.combine(dummy_date, timeval)
    added_datetime = full_datetime + datetime.timedelta(seconds=secs_to_add)
    return added_datetime.time()

Этот подробный код может быть сжат до этой остроты:

(datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time()

, но я думаю, что хотел бы обернуть это в функции для ясности кода так или иначе.

11
ответ дан Paul Stephenson 23 November 2019 в 00:43
поделиться

Попытайтесь добавить datetime.datetime к datetime.timedelta. Если Вы только хотите часть времени, можно звонить time() метод на результанте datetime.datetime объект получить ее.

1
ответ дан Tshilidzi Mudau 23 November 2019 в 00:43
поделиться

Старый вопрос, но я полагал, что добавлю функцию, которая обрабатывает часовые пояса. Ключевые роли передают datetime.time объект tzinfo атрибут в объединение и затем используют timetz() вместо time() на получающейся фиктивной дате и времени. Этот ответ, частично вдохновленный другими ответами здесь.

def add_timedelta_to_time(t, td):
    """Add a timedelta object to a time object using a dummy datetime.

    :param t: datetime.time object.
    :param td: datetime.timedelta object.

    :returns: datetime.time object, representing the result of t + td.

    NOTE: Using a gigantic td may result in an overflow. You've been
    warned.
    """
    # Create a dummy date object.
    dummy_date = date(year=100, month=1, day=1)

    # Combine the dummy date with the given time.
    dummy_datetime = datetime.combine(date=dummy_date, time=t, tzinfo=t.tzinfo)

    # Add the timedelta to the dummy datetime.
    new_datetime = dummy_datetime + td

    # Return the resulting time, including timezone information.
    return new_datetime.timetz()

И вот действительно простой класс тестового сценария (использующий встроенный unittest):

import unittest
from datetime import datetime, timezone, timedelta, time

class AddTimedeltaToTimeTestCase(unittest.TestCase):
    """Test add_timedelta_to_time."""

    def test_wraps(self):
        t = time(hour=23, minute=59)
        td = timedelta(minutes=2)
        t_expected = time(hour=0, minute=1)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)

    def test_tz(self):
        t = time(hour=4, minute=16, tzinfo=timezone.utc)
        td = timedelta(hours=10, minutes=4)
        t_expected = time(hour=14, minute=20, tzinfo=timezone.utc)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)


if __name__ == '__main__':
    unittest.main()
0
ответ дан 23 November 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: