Как отформатировать данные datetime, чтобы они соответствовали полю даты Google Calendar API? - PullRequest
0 голосов
/ 29 мая 2020

Цель: создать событие Календаря Google.

Блокировщик: форматирование даты.


фон: я пытаюсь создать планировщик еды, который берет рецепты из заданной базы данных и создает события с их названием в календаре Google. База данных выглядит так:

d = {'recipe_id': ['carrot salad', 'leek fritters'], 'meal_date': ['2020-05-28 22:28:01.204464+00:00', '2020-05-29 22:28:01.204464+00:00']}    
df = pd.DataFrame(data=d)

дата приема пищи - произведение двух

today_date = datetime.datetime.utcnow().isoformat() + 'Z'
df['menu_date'] = today_date
df['menu_date'] = pd.to_datetime(df['menu_date'])
df['meal_date'] = df['menu_date'] + df['meal'].apply(pd.offsets.Day)

Где «еда» - это просто число (1, 2, et c) и последняя команда просто сдвигает сегодняшнюю дату на эту величину.

Когда я использую следующий код для загрузки в календарь Google, я получаю сообщение об ошибке:

def myconverter(o):
    '''
    call the __str__ method of the datetime object that will return a string representation of the value
    ___

    shoutout: https://code-maven.com/serialize-datetime-object-as-json-in-python
    '''
    if isinstance(o, datetime.datetime):
        return o.__str__()

def add_to_calendar(df, calendar_id):
    """Shows basic usage of the Google Calendar API.
    Prints the start and name of the next 10 events on the user's calendar.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('calendar', 'v3', credentials=creds)

    # Call the Calendar API
    now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
    print('Adding meals to calendar')

    for i, r in df.iterrows():
        event = {
        'summary': r.name,
        'description': r.meal_period,
        'start': {
            'date': json.dumps(r.meal_date, default=myconverter),
            'timeZone': 'America/Los_Angeles'
        },
        'end': {
            'date': json.dumps(r.meal_date, default=myconverter),
            'timeZone': 'America/Los_Angeles'
        }
        }
        event = service.events().insert(calendarId=calendar_id, body=event).execute()

запуская этот код, я получаю следующая ошибка:

HttpError: <HttpError 400 when requesting https://www.googleapis.com/calendar/v3/calendars/CALENDAR_ID/events?alt=json returned "Invalid value for: Invalid format: ""2020-05-28 22:28:01.204464+00:00""">

где CALENDAR_ID - это мой идентификатор календаря Google.

Если кто-нибудь знает, как исправить эту проблему с датой с помощью кода python, это было бы невероятно полезно.

1 Ответ

3 голосов
/ 29 мая 2020

Как насчет этого ответа?

Очки модификации:

  • Если вы хотите использовать start.date и end.date как мероприятие на весь день, формат необходим для быть yyyy-mm-dd. В этом случае timeZone не требуется.
  • Если вы хотите использовать start.dateTime и end.dateTime в качестве события на весь день, формат должен быть RFC3339. В этом случае требуется timeZone.

Из приведенных выше ситуаций, когда ваш скрипт изменен, как насчет следующих шаблонов?

Шаблон 1:

В этом шаблон, используются start.date и end.date. Для этого внесите следующие изменения.

От:

'start': {
    'date': json.dumps(r.meal_date, default=myconverter),
    'timeZone': 'America/Los_Angeles'
},
'end': {
    'date': json.dumps(r.meal_date, default=myconverter),
    'timeZone': 'America/Los_Angeles'
}

Кому:

'start': {
    'date': 'date': parse(r.meal_date).strftime("%Y-%m-%d"),
},
'end': {
    'date': 'date': parse(r.meal_date).strftime("%Y-%m-%d"),
}

Шаблон 2:

В этом шаблоне * Используются 1032 * и end.dateTime. Для этого внесите следующие изменения.

От:

'start': {
    'date': json.dumps(r.meal_date, default=myconverter),
    'timeZone': 'America/Los_Angeles'
},
'end': {
    'date': json.dumps(r.meal_date, default=myconverter),
    'timeZone': 'America/Los_Angeles'
}

Кому:

'start': {
    'dateTime': parse(r.meal_date).isoformat(),
    'timeZone': 'America/Los_Angeles'
},
'end': {
    'dateTime': parse(r.meal_date).isoformat(),
    'timeZone': 'America/Los_Angeles'
}

Примечание:

  • В данной модификации , Используется from dateutil.parser import parse.
  • Из вашего скрипта я не видел, какой объем вы используете. Поэтому, если возникает ошибка, связанная с областью действия, используйте https://www.googleapis.com/auth/calendar в качестве области действия. В это время удалите файл token.pickle и повторно авторизуйте область. Пожалуйста, будьте осторожны.

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...