[FIX] *: adapt tz for Ubuntu Noble
Some of the non canononical timezones are not present in Ubuntu Noble, it would be a better practice to only use canonical timezones in data and tests. Note that this is not a real fix for all cases since the database that ran on Ubuntu Jammy and are moved to an ubuntu Noble server will have the issue with timezones already in database. One of the possible fix would be to manage that during upgrades, but this isn't a verry flexible solution since upgrade are meant to manage chyange of version, not change of server. If an old 17.0 versions needs to be moved to a Noble server, this won't work. Another solution would be to install package like tzdata-legacy that may keep the old timezones but it is not the only think since TAI-10 are also in this package. This solution is not ideal because non canonical timezone will still be shown in the dropdown. We would need to filter them. A last solution would be to add the support for those old timezones by monkeypatching the lib. This way, only new timezones would be shown but non canonical one won't crash when used. This is not ideal either because we may need to keep this for a while. But in combination with the upgrade solution, it may work proprely. Part-of: odoo/odoo#160842
This commit is contained in:
@@ -529,14 +529,14 @@ class RecurrenceRule(models.Model):
|
|||||||
# Given the following recurrence:
|
# Given the following recurrence:
|
||||||
# - monthly
|
# - monthly
|
||||||
# - 1st of each month
|
# - 1st of each month
|
||||||
# - timezone US/Eastern (UTC−05:00)
|
# - timezone America/New_York (UTC−05:00)
|
||||||
# - at 6am US/Eastern = 11am UTC
|
# - at 6am America/New_York = 11am UTC
|
||||||
# - from 2019/02/01 to 2019/05/01.
|
# - from 2019/02/01 to 2019/05/01.
|
||||||
# The naive way would be to store:
|
# The naive way would be to store:
|
||||||
# 2019/02/01 11:00 - 2019/03/01 11:00 - 2019/04/01 11:00 - 2019/05/01 11:00 (UTC)
|
# 2019/02/01 11:00 - 2019/03/01 11:00 - 2019/04/01 11:00 - 2019/05/01 11:00 (UTC)
|
||||||
#
|
#
|
||||||
# But a DST change occurs on 2019/03/10 in US/Eastern timezone. US/Eastern is now UTC−04:00.
|
# But a DST change occurs on 2019/03/10 in America/New_York timezone. America/New_York is now UTC−04:00.
|
||||||
# From this point in time, 11am (UTC) is actually converted to 7am (US/Eastern) instead of the expected 6am!
|
# From this point in time, 11am (UTC) is actually converted to 7am (America/New_York) instead of the expected 6am!
|
||||||
# What should be stored is:
|
# What should be stored is:
|
||||||
# 2019/02/01 11:00 - 2019/03/01 11:00 - 2019/04/01 10:00 - 2019/05/01 10:00 (UTC)
|
# 2019/02/01 11:00 - 2019/03/01 11:00 - 2019/04/01 10:00 - 2019/05/01 10:00 (UTC)
|
||||||
# ***** *****
|
# ***** *****
|
||||||
|
|||||||
@@ -218,14 +218,14 @@ class TestCalendar(SavepointCaseWithUserDemo):
|
|||||||
self.assertEqual(d.minute, 30)
|
self.assertEqual(d.minute, 30)
|
||||||
|
|
||||||
def test_recurring_ny(self):
|
def test_recurring_ny(self):
|
||||||
self.user_demo.tz = 'US/Eastern'
|
self.user_demo.tz = 'America/New_York'
|
||||||
event = self.CalendarEvent.create({'user_id': self.user_demo.id, 'name': 'test', 'partner_ids': [Command.link(self.user_demo.partner_id.id)]})
|
event = self.CalendarEvent.create({'user_id': self.user_demo.id, 'name': 'test', 'partner_ids': [Command.link(self.user_demo.partner_id.id)]})
|
||||||
f = Form(event.with_context(tz='US/Eastern').with_user(self.user_demo))
|
f = Form(event.with_context(tz='America/New_York').with_user(self.user_demo))
|
||||||
f.name = 'test'
|
f.name = 'test'
|
||||||
f.start = '2022-07-07 01:00:00' # This is in UTC. In NY, it corresponds to the 6th of july at 9pm.
|
f.start = '2022-07-07 01:00:00' # This is in UTC. In NY, it corresponds to the 6th of july at 9pm.
|
||||||
f.recurrency = True
|
f.recurrency = True
|
||||||
self.assertEqual(f.weekday, 'WED')
|
self.assertEqual(f.weekday, 'WED')
|
||||||
self.assertEqual(f.event_tz, 'US/Eastern', "The value should correspond to the user tz")
|
self.assertEqual(f.event_tz, 'America/New_York', "The value should correspond to the user tz")
|
||||||
self.assertEqual(f.count, 1, "The default value should be displayed")
|
self.assertEqual(f.count, 1, "The default value should be displayed")
|
||||||
self.assertEqual(f.interval, 1, "The default value should be displayed")
|
self.assertEqual(f.interval, 1, "The default value should be displayed")
|
||||||
self.assertEqual(f.month_by, "date", "The default value should be displayed")
|
self.assertEqual(f.month_by, "date", "The default value should be displayed")
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||||||
'rrule_type': 'weekly',
|
'rrule_type': 'weekly',
|
||||||
'mon': True,
|
'mon': True,
|
||||||
'count': '2',
|
'count': '2',
|
||||||
'event_tz': 'US/Eastern', # DST change on 2002/10/27
|
'event_tz': 'America/New_York', # DST change on 2002/10/27
|
||||||
})
|
})
|
||||||
recurrence = self.env['calendar.recurrence'].search([('base_event_id', '=', self.event.id)])
|
recurrence = self.env['calendar.recurrence'].search([('base_event_id', '=', self.event.id)])
|
||||||
self.assertEventDates(recurrence.calendar_event_ids, [
|
self.assertEventDates(recurrence.calendar_event_ids, [
|
||||||
@@ -226,9 +226,9 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||||||
|
|
||||||
def test_ambiguous_dst_time_winter(self):
|
def test_ambiguous_dst_time_winter(self):
|
||||||
""" Test hours stays the same, regardless of DST changes """
|
""" Test hours stays the same, regardless of DST changes """
|
||||||
eastern = pytz.timezone('US/Eastern')
|
eastern = pytz.timezone('America/New_York')
|
||||||
dt = eastern.localize(datetime(2002, 10, 20, 1, 30, 00)).astimezone(pytz.utc).replace(tzinfo=None)
|
dt = eastern.localize(datetime(2002, 10, 20, 1, 30, 00)).astimezone(pytz.utc).replace(tzinfo=None)
|
||||||
# Next occurence happens at 1:30am on 27th Oct 2002 which happened twice in the US/Eastern
|
# Next occurence happens at 1:30am on 27th Oct 2002 which happened twice in the America/New_York
|
||||||
# timezone when the clocks where put back at the end of Daylight Saving Time
|
# timezone when the clocks where put back at the end of Daylight Saving Time
|
||||||
self.event.start = dt
|
self.event.start = dt
|
||||||
self.event.stop = dt + relativedelta(hours=1)
|
self.event.stop = dt + relativedelta(hours=1)
|
||||||
@@ -237,7 +237,7 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||||||
'rrule_type': 'weekly',
|
'rrule_type': 'weekly',
|
||||||
'sun': True,
|
'sun': True,
|
||||||
'count': '2',
|
'count': '2',
|
||||||
'event_tz': 'US/Eastern' # DST change on 2002/4/7
|
'event_tz': 'America/New_York' # DST change on 2002/4/7
|
||||||
})
|
})
|
||||||
events = self.event.recurrence_id.calendar_event_ids
|
events = self.event.recurrence_id.calendar_event_ids
|
||||||
self.assertEqual(events.mapped('duration'), [1, 1])
|
self.assertEqual(events.mapped('duration'), [1, 1])
|
||||||
@@ -248,10 +248,10 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||||||
|
|
||||||
def test_ambiguous_dst_time_spring(self):
|
def test_ambiguous_dst_time_spring(self):
|
||||||
""" Test hours stays the same, regardless of DST changes """
|
""" Test hours stays the same, regardless of DST changes """
|
||||||
eastern = pytz.timezone('US/Eastern')
|
eastern = pytz.timezone('America/New_York')
|
||||||
dt = eastern.localize(datetime(2002, 3, 31, 2, 30, 00)).astimezone(pytz.utc).replace(tzinfo=None)
|
dt = eastern.localize(datetime(2002, 3, 31, 2, 30, 00)).astimezone(pytz.utc).replace(tzinfo=None)
|
||||||
# Next occurence happens 2:30am on 7th April 2002 which never happened at all in the
|
# Next occurence happens 2:30am on 7th April 2002 which never happened at all in the
|
||||||
# US/Eastern timezone, as the clocks where put forward at 2:00am skipping the entire hour
|
# America/New_York timezone, as the clocks where put forward at 2:00am skipping the entire hour
|
||||||
self.event.start = dt
|
self.event.start = dt
|
||||||
self.event.stop = dt + relativedelta(hours=1)
|
self.event.stop = dt + relativedelta(hours=1)
|
||||||
self.event._apply_recurrence_values({
|
self.event._apply_recurrence_values({
|
||||||
@@ -259,7 +259,7 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
|
|||||||
'rrule_type': 'weekly',
|
'rrule_type': 'weekly',
|
||||||
'sun': True,
|
'sun': True,
|
||||||
'count': '2',
|
'count': '2',
|
||||||
'event_tz': 'US/Eastern' # DST change on 2002/4/7
|
'event_tz': 'America/New_York' # DST change on 2002/4/7
|
||||||
})
|
})
|
||||||
events = self.event.recurrence_id.calendar_event_ids
|
events = self.event.recurrence_id.calendar_event_ids
|
||||||
self.assertEqual(events.mapped('duration'), [1, 1])
|
self.assertEqual(events.mapped('duration'), [1, 1])
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<field name="seats_limited">True</field>
|
<field name="seats_limited">True</field>
|
||||||
<field name="seats_max">50</field>
|
<field name="seats_max">50</field>
|
||||||
<field name="address_id" ref="event.res_partner_location_2"/>
|
<field name="address_id" ref="event.res_partner_location_2"/>
|
||||||
<field name="date_tz">US/Pacific</field>
|
<field name="date_tz">America/Los_Angeles</field>
|
||||||
<field name="event_type_id" ref="event_type_0"/>
|
<field name="event_type_id" ref="event_type_0"/>
|
||||||
<field name="stage_id" ref="event_stage_booked"/>
|
<field name="stage_id" ref="event_stage_booked"/>
|
||||||
<field name="tag_ids" eval="[(4, ref('event.event_tag_category_1_tag_1')), (4, ref('event.event_tag_category_2_tag_1'))]"/>
|
<field name="tag_ids" eval="[(4, ref('event.event_tag_category_1_tag_1')), (4, ref('event.event_tag_category_2_tag_1'))]"/>
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
<field name="seats_limited">True</field>
|
<field name="seats_limited">True</field>
|
||||||
<field name="seats_max">4</field>
|
<field name="seats_max">4</field>
|
||||||
<field name="address_id" ref="event.res_partner_location_2"/>
|
<field name="address_id" ref="event.res_partner_location_2"/>
|
||||||
<field name="date_tz">US/Pacific</field>
|
<field name="date_tz">America/Los_Angeles</field>
|
||||||
<field name="event_type_id" ref="event_type_1"/>
|
<field name="event_type_id" ref="event_type_1"/>
|
||||||
<field name="stage_id" ref="event_stage_done"/>
|
<field name="stage_id" ref="event_stage_done"/>
|
||||||
<field name="kanban_state">done</field>
|
<field name="kanban_state">done</field>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</record>
|
</record>
|
||||||
<record id="event_type_2" model="event.type">
|
<record id="event_type_2" model="event.type">
|
||||||
<field name="name">Sport</field>
|
<field name="name">Sport</field>
|
||||||
<field name="default_timezone">US/Pacific</field>
|
<field name="default_timezone">America/Los_Angeles</field>
|
||||||
<field name="sequence">5</field>
|
<field name="sequence">5</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class TestEventData(TestEventInternalsCommon):
|
|||||||
event.write({
|
event.write({
|
||||||
'date_begin': datetime(2020, 1, 31, 14, 30, 0),
|
'date_begin': datetime(2020, 1, 31, 14, 30, 0),
|
||||||
'date_end': datetime(2020, 2, 1, 2, 0, 0),
|
'date_end': datetime(2020, 2, 1, 2, 0, 0),
|
||||||
'date_tz': 'Mexico/General'
|
'date_tz': 'America/Mexico_City'
|
||||||
})
|
})
|
||||||
self.assertTrue(event.is_one_day)
|
self.assertTrue(event.is_one_day)
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ class TestEventData(TestEventInternalsCommon):
|
|||||||
event.write({
|
event.write({
|
||||||
'date_begin': datetime(2020, 1, 31, 14, 30, 0),
|
'date_begin': datetime(2020, 1, 31, 14, 30, 0),
|
||||||
'date_end': datetime(2020, 2, 1, 2, 0, 0),
|
'date_end': datetime(2020, 2, 1, 2, 0, 0),
|
||||||
'date_tz': 'Mexico/General'
|
'date_tz': 'America/Mexico_City'
|
||||||
})
|
})
|
||||||
self.assertTrue(event.is_one_day)
|
self.assertTrue(event.is_one_day)
|
||||||
self.assertFalse(event.is_ongoing)
|
self.assertFalse(event.is_ongoing)
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ class TestSelfAccessRights(TestHrCommon):
|
|||||||
self.env['ir.config_parameter'].set_param('hr.hr_employee_self_edit', False)
|
self.env['ir.config_parameter'].set_param('hr.hr_employee_self_edit', False)
|
||||||
# should not raise
|
# should not raise
|
||||||
vals = [
|
vals = [
|
||||||
{'tz': "Australia/ACT"},
|
{'tz': "Australia/Sydney"},
|
||||||
{'email': "new@example.com"},
|
{'email': "new@example.com"},
|
||||||
{'signature': "<p>I'm Richard!</p>"},
|
{'signature': "<p>I'm Richard!</p>"},
|
||||||
{'notification_type': "email"},
|
{'notification_type': "email"},
|
||||||
@@ -193,7 +193,7 @@ class TestSelfAccessRights(TestHrCommon):
|
|||||||
# they are in SELF_READABLE_FIELDS
|
# they are in SELF_READABLE_FIELDS
|
||||||
self.env['ir.config_parameter'].set_param('hr.hr_employee_self_edit', False)
|
self.env['ir.config_parameter'].set_param('hr.hr_employee_self_edit', False)
|
||||||
vals = [
|
vals = [
|
||||||
{'tz': "Australia/ACT"},
|
{'tz': "Australia/Sydney"},
|
||||||
{'email': "new@example.com"},
|
{'email': "new@example.com"},
|
||||||
{'signature': "<p>I'm Richard!</p>"},
|
{'signature': "<p>I'm Richard!</p>"},
|
||||||
{'notification_type': "email"},
|
{'notification_type': "email"},
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class TestGlobalLeaves(TestHrHolidaysCommon):
|
|||||||
"""
|
"""
|
||||||
calendar_asia = self.env['resource.calendar'].create({
|
calendar_asia = self.env['resource.calendar'].create({
|
||||||
'name': 'Asia calendar',
|
'name': 'Asia calendar',
|
||||||
'tz': 'Asia/Calcutta', # UTC +05:30
|
'tz': 'Asia/Kolkata', # UTC +05:30
|
||||||
'hours_per_day': 8.0,
|
'hours_per_day': 8.0,
|
||||||
'attendance_ids': []
|
'attendance_ids': []
|
||||||
})
|
})
|
||||||
@@ -124,12 +124,12 @@ class TestGlobalLeaves(TestHrHolidaysCommon):
|
|||||||
})
|
})
|
||||||
# Expectation:
|
# Expectation:
|
||||||
# 6:00:00 in UTC (data from the browser) --> 8:00:00 for Europe/Brussel (UTC +02:00)
|
# 6:00:00 in UTC (data from the browser) --> 8:00:00 for Europe/Brussel (UTC +02:00)
|
||||||
# 8:00:00 for Asia/Calcutta (UTC +05:30) --> 2:30:00 in UTC
|
# 8:00:00 for Asia/Kolkata (UTC +05:30) --> 2:30:00 in UTC
|
||||||
self.assertEqual(global_leave.date_from, datetime(2023, 5, 15, 2, 30))
|
self.assertEqual(global_leave.date_from, datetime(2023, 5, 15, 2, 30))
|
||||||
self.assertEqual(global_leave.date_to, datetime(2023, 5, 15, 11, 30))
|
self.assertEqual(global_leave.date_to, datetime(2023, 5, 15, 11, 30))
|
||||||
# Note:
|
# Note:
|
||||||
# The user in Europe/Brussels timezone see 4:30 and not 2:30 because he is in UTC +02:00.
|
# The user in Europe/Brussels timezone see 4:30 and not 2:30 because he is in UTC +02:00.
|
||||||
# The user in Asia/Calcutta timezone (determined via the browser) see 8:00 because he is in UTC +05:30
|
# The user in Asia/Kolkata timezone (determined via the browser) see 8:00 because he is in UTC +05:30
|
||||||
|
|
||||||
def test_global_leave_number_of_days_with_new(self):
|
def test_global_leave_number_of_days_with_new(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ class TestLeaveRequests(TestHrHolidaysCommon):
|
|||||||
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||||
def test_timezone_employee_leave_request(self):
|
def test_timezone_employee_leave_request(self):
|
||||||
""" Create a leave request for an employee in another timezone """
|
""" Create a leave request for an employee in another timezone """
|
||||||
self.employee_emp.tz = 'NZ' # GMT+12
|
self.employee_emp.tz = 'Pacific/Auckland' # GMT+12
|
||||||
leave = self.env['hr.leave'].new({
|
leave = self.env['hr.leave'].new({
|
||||||
'employee_id': self.employee_emp.id,
|
'employee_id': self.employee_emp.id,
|
||||||
'holiday_status_id': self.holidays_type_1.id,
|
'holiday_status_id': self.holidays_type_1.id,
|
||||||
@@ -273,7 +273,7 @@ class TestLeaveRequests(TestHrHolidaysCommon):
|
|||||||
def test_timezone_company_leave_request(self):
|
def test_timezone_company_leave_request(self):
|
||||||
""" Create a leave request for a company in another timezone """
|
""" Create a leave request for a company in another timezone """
|
||||||
company = self.env['res.company'].create({'name': "Hergé"})
|
company = self.env['res.company'].create({'name': "Hergé"})
|
||||||
company.resource_calendar_id.tz = 'NZ' # GMT+12
|
company.resource_calendar_id.tz = 'Australia/Sydney' # GMT+12
|
||||||
leave = self.env['hr.leave'].new({
|
leave = self.env['hr.leave'].new({
|
||||||
'employee_id': self.employee_emp.id,
|
'employee_id': self.employee_emp.id,
|
||||||
'holiday_status_id': self.holidays_type_1.id,
|
'holiday_status_id': self.holidays_type_1.id,
|
||||||
@@ -291,7 +291,7 @@ class TestLeaveRequests(TestHrHolidaysCommon):
|
|||||||
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||||
def test_timezone_company_validated(self):
|
def test_timezone_company_validated(self):
|
||||||
""" Create a leave request for a company in another timezone and validate it """
|
""" Create a leave request for a company in another timezone and validate it """
|
||||||
self.env.user.tz = 'NZ' # GMT+12
|
self.env.user.tz = 'Australia/Sydney' # GMT+12
|
||||||
company = self.env['res.company'].create({'name': "Hergé"})
|
company = self.env['res.company'].create({'name': "Hergé"})
|
||||||
employee = self.env['hr.employee'].create({'name': "Remi", 'company_id': company.id})
|
employee = self.env['hr.employee'].create({'name': "Remi", 'company_id': company.id})
|
||||||
leave_form = Form(self.env['hr.leave'], view='hr_holidays.hr_leave_view_form_manager')
|
leave_form = Form(self.env['hr.leave'], view='hr_holidays.hr_leave_view_form_manager')
|
||||||
@@ -313,7 +313,7 @@ class TestLeaveRequests(TestHrHolidaysCommon):
|
|||||||
def test_timezone_department_leave_request(self):
|
def test_timezone_department_leave_request(self):
|
||||||
""" Create a leave request for a department in another timezone """
|
""" Create a leave request for a department in another timezone """
|
||||||
company = self.env['res.company'].create({'name': "Hergé"})
|
company = self.env['res.company'].create({'name': "Hergé"})
|
||||||
company.resource_calendar_id.tz = 'NZ' # GMT+12
|
company.resource_calendar_id.tz = 'Australia/Sydney' # GMT+12
|
||||||
department = self.env['hr.department'].create({'name': "Museum", 'company_id': company.id})
|
department = self.env['hr.department'].create({'name': "Museum", 'company_id': company.id})
|
||||||
leave = self.env['hr.leave'].new({
|
leave = self.env['hr.leave'].new({
|
||||||
'employee_id': self.employee_emp.id,
|
'employee_id': self.employee_emp.id,
|
||||||
@@ -470,7 +470,7 @@ class TestLeaveRequests(TestHrHolidaysCommon):
|
|||||||
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
|
||||||
def test_leave_defaults_with_timezones(self):
|
def test_leave_defaults_with_timezones(self):
|
||||||
""" Make sure that leaves start with correct defaults for non-UTC timezones """
|
""" Make sure that leaves start with correct defaults for non-UTC timezones """
|
||||||
timezones_to_test = ('UTC', 'Pacific/Midway', 'US/Pacific', 'Asia/Taipei', 'Pacific/Kiritimati') # UTC, UTC -11, UTC -8, UTC +8, UTC +14
|
timezones_to_test = ('UTC', 'Pacific/Midway', 'America/Los_Angeles', 'Asia/Taipei', 'Pacific/Kiritimati') # UTC, UTC -11, UTC -8, UTC +8, UTC +14
|
||||||
|
|
||||||
# January 2020
|
# January 2020
|
||||||
# Su Mo Tu We Th Fr Sa
|
# Su Mo Tu We Th Fr Sa
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class TestCurrencyRates(TransactionCase):
|
|||||||
"rate": CAD_UTC,
|
"rate": CAD_UTC,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.env.user.tz = "Australia/ACT"
|
self.env.user.tz = "Australia/Sydney"
|
||||||
self.env["res.currency.rate"].create(
|
self.env["res.currency.rate"].create(
|
||||||
{
|
{
|
||||||
"currency_id": cad.id,
|
"currency_id": cad.id,
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ class TestActivityMixin(TestActivityCommon):
|
|||||||
name='user Australia',
|
name='user Australia',
|
||||||
login='user Australia',
|
login='user Australia',
|
||||||
)
|
)
|
||||||
cls.user_australia.tz = 'Australia/ACT'
|
cls.user_australia.tz = 'Australia/Sydney'
|
||||||
|
|
||||||
@mute_logger('odoo.addons.mail.models.mail_mail')
|
@mute_logger('odoo.addons.mail.models.mail_mail')
|
||||||
def test_activity_mixin(self):
|
def test_activity_mixin(self):
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class TestResourceCommon(TransactionCase):
|
|||||||
(0, 0, 0, '1', 'line_section', 10), (8, 16, 0, '1', False, 11), (7, 15, 2, '1', False, 12),
|
(0, 0, 0, '1', 'line_section', 10), (8, 16, 0, '1', False, 11), (7, 15, 2, '1', False, 12),
|
||||||
(8, 16, 3, '1', False, 13), (10, 16, 4, '1', False, 14)], 'Europe/Brussels')
|
(8, 16, 3, '1', False, 13), (10, 16, 4, '1', False, 14)], 'Europe/Brussels')
|
||||||
|
|
||||||
cls.calendar_paul = cls._define_calendar('Morning and evening shifts', sum([((2, 7, i, 0.5), (10, 16, i, 0.5)) for i in range(5)], ()), 'Brazil/DeNoronha')
|
cls.calendar_paul = cls._define_calendar('Morning and evening shifts', sum([((2, 7, i, 0.5), (10, 16, i, 0.5)) for i in range(5)], ()), 'America/Noronha')
|
||||||
|
|
||||||
cls.calendar_bob = cls._define_calendar('Calendar with adjacent attendances', sum([((8, 12, i, 0.5), (12, 16, i, 0.5)) for i in range(5)], ()), 'Europe/Brussels')
|
cls.calendar_bob = cls._define_calendar('Calendar with adjacent attendances', sum([((8, 12, i, 0.5), (12, 16, i, 0.5)) for i in range(5)], ()), 'Europe/Brussels')
|
||||||
|
|
||||||
|
|||||||
@@ -651,16 +651,16 @@ class TestResMixin(TestResourceCommon):
|
|||||||
def test_adjust_calendar_timezone_before(self):
|
def test_adjust_calendar_timezone_before(self):
|
||||||
# Calendar:
|
# Calendar:
|
||||||
# Every day 8-16
|
# Every day 8-16
|
||||||
self.jean.tz = 'Japan'
|
self.jean.tz = 'Asia/Tokyo'
|
||||||
self.calendar_jean.tz = 'Europe/Brussels'
|
self.calendar_jean.tz = 'Europe/Brussels'
|
||||||
|
|
||||||
result = self.jean._adjust_to_calendar(
|
result = self.jean._adjust_to_calendar(
|
||||||
datetime_tz(2020, 4, 1, 0, 0, 0, tzinfo='Japan'),
|
datetime_tz(2020, 4, 1, 0, 0, 0, tzinfo='Asia/Tokyo'),
|
||||||
datetime_tz(2020, 4, 1, 23, 59, 59, tzinfo='Japan'),
|
datetime_tz(2020, 4, 1, 23, 59, 59, tzinfo='Asia/Tokyo'),
|
||||||
)
|
)
|
||||||
self.assertEqual(result[self.jean], (
|
self.assertEqual(result[self.jean], (
|
||||||
datetime_tz(2020, 4, 1, 8, 0, 0, tzinfo='Japan'),
|
datetime_tz(2020, 4, 1, 8, 0, 0, tzinfo='Asia/Tokyo'),
|
||||||
datetime_tz(2020, 4, 1, 16, 0, 0, tzinfo='Japan'),
|
datetime_tz(2020, 4, 1, 16, 0, 0, tzinfo='Asia/Tokyo'),
|
||||||
), "It should have found a starting time the 1st")
|
), "It should have found a starting time the 1st")
|
||||||
|
|
||||||
def test_adjust_calendar_timezone_after(self):
|
def test_adjust_calendar_timezone_after(self):
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ from . import test_search
|
|||||||
from . import test_split_table
|
from . import test_split_table
|
||||||
from . import test_sql
|
from . import test_sql
|
||||||
from . import test_translate
|
from . import test_translate
|
||||||
|
from . import test_tz
|
||||||
# from . import test_uninstall # loop
|
# from . import test_uninstall # loop
|
||||||
from . import test_user_has_group
|
from . import test_user_has_group
|
||||||
from . import test_views
|
from . import test_views
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ class TestFormatLangDate(TransactionCase):
|
|||||||
|
|
||||||
# -- test `time`
|
# -- test `time`
|
||||||
time_part = datetime.time(16, 30, 22)
|
time_part = datetime.time(16, 30, 22)
|
||||||
time_part_tz = datetime.time(16, 30, 22, tzinfo=pytz.timezone('US/Eastern')) # 4:30 PM timezoned
|
time_part_tz = datetime.time(16, 30, 22, tzinfo=pytz.timezone('America/New_York')) # 4:30 PM timezoned
|
||||||
|
|
||||||
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, time_part, time_format='HH:mm:ss'), '16:30:22')
|
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, time_part, time_format='HH:mm:ss'), '16:30:22')
|
||||||
self.assertEqual(misc.format_time(lang.with_context(lang='zh_CN').env, time_part, time_format="ah:m:ss"), '\u4e0b\u53484:30:22')
|
self.assertEqual(misc.format_time(lang.with_context(lang='zh_CN').env, time_part, time_format="ah:m:ss"), '\u4e0b\u53484:30:22')
|
||||||
@@ -306,7 +306,7 @@ class TestFormatLangDate(TransactionCase):
|
|||||||
|
|
||||||
#Check timezone conversion in format_time
|
#Check timezone conversion in format_time
|
||||||
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, datetime_str, 'Europe/Brussels', time_format='HH:mm:ss Z'), '11:33:00 +0100')
|
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, datetime_str, 'Europe/Brussels', time_format='HH:mm:ss Z'), '11:33:00 +0100')
|
||||||
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, datetime_str, 'US/Eastern', time_format='HH:mm:ss Z'), '05:33:00 -0500')
|
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, datetime_str, 'America/New_York', time_format='HH:mm:ss Z'), '05:33:00 -0500')
|
||||||
|
|
||||||
# Check given `lang_code` overwites context lang
|
# Check given `lang_code` overwites context lang
|
||||||
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, time_part, time_format='ah:mm', lang_code='zh_CN'), '\u4e0b\u53484:30')
|
self.assertEqual(misc.format_time(lang.with_context(lang='fr_FR').env, time_part, time_format='ah:mm', lang_code='zh_CN'), '\u4e0b\u53484:30')
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import pytz
|
||||||
|
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestTZ(TransactionCase):
|
||||||
|
|
||||||
|
def test_tz_legacy(self):
|
||||||
|
#See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
|
def assertTZEqual(tz1, tz2):
|
||||||
|
self.assertEqual(tz1._utcoffset, tz2._utcoffset)
|
||||||
|
self.assertEqual(tz1._transition_info, tz2._transition_info)
|
||||||
|
|
||||||
|
assertTZEqual(pytz.timezone('US/Eastern'), pytz.timezone('America/New_York'))
|
||||||
|
assertTZEqual(pytz.timezone('US/Central'), pytz.timezone('America/Chicago'))
|
||||||
|
assertTZEqual(pytz.timezone('US/Mountain'), pytz.timezone('America/Denver'))
|
||||||
|
assertTZEqual(pytz.timezone('US/Pacific'), pytz.timezone('America/Los_Angeles'))
|
||||||
|
assertTZEqual(pytz.timezone('US/Alaska'), pytz.timezone('America/Anchorage'))
|
||||||
|
assertTZEqual(pytz.timezone('US/Hawaii'), pytz.timezone('Pacific/Honolulu'))
|
||||||
|
assertTZEqual(pytz.timezone('Canada/Atlantic'), pytz.timezone('America/Halifax'))
|
||||||
|
assertTZEqual(pytz.timezone('Canada/Pacific'), pytz.timezone('America/Vancouver'))
|
||||||
|
assertTZEqual(pytz.timezone('Mexico/BajaNorte'), pytz.timezone('America/Tijuana'))
|
||||||
|
assertTZEqual(pytz.timezone('Mexico/General'), pytz.timezone('America/Mexico_City'))
|
||||||
|
assertTZEqual(pytz.timezone('Brazil/East'), pytz.timezone('America/Sao_Paulo'))
|
||||||
|
# This one is not correct for a strange reason
|
||||||
|
#assertTZEqual(pytz.timezone('Pacific/Midway'), pytz.timezone('Pacific/Pago_Pago'))
|
||||||
|
|
||||||
|
def test_cannot_set_deprecated_timezone(self):
|
||||||
|
# this should be ok
|
||||||
|
self.env.user.tz = "America/New_York"
|
||||||
|
if "US/Eastern" not in pytz.all_timezones:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.env.user.tz = "US/Eastern"
|
||||||
Reference in New Issue
Block a user