Skip to content

Commit

Permalink
Nextgen Proto Pythonic API: Add duration.py
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 661035580
  • Loading branch information
anandolee authored and copybara-github committed Aug 9, 2024
1 parent 814352c commit 903c3f1
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 2 deletions.
100 changes: 100 additions & 0 deletions python/google/protobuf/duration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""Contains the Duration helper APIs."""

import datetime

from google.protobuf.duration_pb2 import Duration


def from_json_string(value: str) -> Duration:
"""Converts a string to Duration.
Args:
value: A string to be converted. The string must end with 's'. Any
fractional digits (or none) are accepted as long as they fit into
precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s"
Raises:
ValueError: On parsing problems.
"""
duration = Duration()
duration.FromJsonString(value)
return duration


def from_microseconds(micros: float) -> Duration:
"""Converts microseconds to Duration."""
duration = Duration()
duration.FromMicroseconds(micros)
return duration


def from_milliseconds(millis: float) -> Duration:
"""Converts milliseconds to Duration."""
duration = Duration()
duration.FromMilliseconds(millis)
return duration


def from_nanoseconds(nanos: float) -> Duration:
"""Converts nanoseconds to Duration."""
duration = Duration()
duration.FromNanoseconds(nanos)
return duration


def from_seconds(seconds: float) -> Duration:
"""Converts seconds to Duration."""
duration = Duration()
duration.FromSeconds(seconds)
return duration


def from_timedelta(td: datetime.timedelta) -> Duration:
"""Converts timedelta to Duration."""
duration = Duration()
duration.FromTimedelta(td)
return duration


def to_json_string(duration: Duration) -> str:
"""Converts Duration to string format.
Returns:
A string converted from self. The string format will contains
3, 6, or 9 fractional digits depending on the precision required to
represent the exact Duration value. For example: "1s", "1.010s",
"1.000000100s", "-3.100s"
"""
return duration.ToJsonString()


def to_microseconds(duration: Duration) -> int:
"""Converts a Duration to microseconds."""
return duration.ToMicroseconds()


def to_milliseconds(duration: Duration) -> int:
"""Converts a Duration to milliseconds."""
return duration.ToMilliseconds()


def to_nanoseconds(duration: Duration) -> int:
"""Converts a Duration to nanoseconds."""
return duration.ToNanoseconds()


def to_seconds(duration: Duration) -> int:
"""Converts a Duration to seconds."""
return duration.ToSeconds()


def to_timedelta(duration: Duration) -> datetime.timedelta:
"""Converts Duration to timedelta."""
return duration.ToTimedelta()
62 changes: 62 additions & 0 deletions python/google/protobuf/internal/duration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""Tests proto Duration APIs."""

import datetime
import unittest

from google.protobuf import duration

from google.protobuf import duration_pb2


class DurationTest(unittest.TestCase):

def test_duration_integer_conversion(self):
self.assertEqual(1, duration.to_nanoseconds(duration.from_nanoseconds(1)))
self.assertEqual(-1, duration.to_seconds(duration.from_seconds(-1)))
self.assertEqual(
123, duration.to_milliseconds(duration.from_milliseconds(123))
)
self.assertEqual(
321, duration.to_microseconds(duration.from_microseconds(321))
)

def test_duration_json(self):

def check_duration(message, text):
self.assertEqual(text, duration.to_json_string(message))
parsed_duration = duration.from_json_string(text)
self.assertEqual(message, parsed_duration)

message = duration_pb2.Duration()
message.seconds = 0
message.nanos = 0
check_duration(message, '0s')
message.nanos = 10000000
check_duration(message, '0.010s')
message.nanos = 10000
check_duration(message, '0.000010s')
message.nanos = 10
check_duration(message, '0.000000010s')

def test_duration_timedelta(self):
message = duration.from_nanoseconds(1999999999)
td = duration.to_timedelta(message)
self.assertEqual(1, td.seconds)
self.assertEqual(999999, td.microseconds)

message = duration.from_microseconds(-1)
td = duration.to_timedelta(message)
converted_message = duration.from_timedelta(td)
self.assertEqual(message, converted_message)


if __name__ == '__main__':
unittest.main()
4 changes: 2 additions & 2 deletions python/google/protobuf/internal/timestamp_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""Tests proto_time_util APIs."""
"""Tests proto Timestamp APIs."""

import datetime
import unittest
Expand All @@ -17,7 +17,7 @@
from google.protobuf import timestamp_pb2


class ProtoTimeUtilTest(unittest.TestCase):
class TimestampTest(unittest.TestCase):

def test_timestamp_integer_conversion(self):
self.assertEqual(1, timestamp.to_nanoseconds(timestamp.from_nanoseconds(1)))
Expand Down

0 comments on commit 903c3f1

Please sign in to comment.