oasis-open / cti-python-stix2

OASIS TC Open Repository: Python APIs for STIX 2
https://stix2.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
356 stars 113 forks source link

How to get Timestamps to only have milliseconds, rather than microseconds #582

Closed brettforbes closed 5 months ago

brettforbes commented 5 months ago

Hi, Once again, great library, well done.

But i am having trouble with timestamps (e.g. created, modified etc.), and getting them to only produce 3 significant figures (i.e. milliseconds), rather than 6 significant figures (i.e. microseconds).

Its confusing, as if you look at the definition of any class, then the timestamp properties generally have the following constraints

('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min'))

so, given the precision is set at milliseconds in the class definition, then one would expect the timestamps to be produced with only 3 significant digits, yet is is generally produced with 6 significant figures, for example:

"created": "2024-01-24T12:38:07.927748Z"

How can I set it so that only 3 significant digits are produced when i initialise a stix object? So for example:

"created": "2024-01-24T12:38:07.927Z"

chisholm commented 5 months ago

precision_constraint is "min", i.e. millisecond is treated as a minimum precision. Versioning timestamps are allowed to be more precise. The constraints were added because of a spec change between STIX 2.0 and 2.1. STIX 2.0 required exactly millisecond precision on versioning timestamps (created/modified) [1]. STIX 2.1 changed it to a minimum precision [2]. So the stix2 library needed to support both.

If you want to limit versioning timestamp precision to millisecond in STIX 2.1 content, you'd have to do that yourself. If you have datetime objects, you could modify the fractional seconds field yourself to zero out low-order digits. There are also some utility functions included with the stix2 library which you could leverage. For example, you could call the format_datetime() function, which accepts precision/constraint args, to create a timestamp string with the precision you require. That would work as a timestamp value when creating a new object (it would be re-parsed as a datetime object again but without the extra precision). The parse_into_datetime() function also accepts either strings or datetime objects, and supports the precision/constraint args. Instead of returning a string, it returns an instance of a datetime subclass (STIXdatetime). So you could pass your datetime object and get another back, with adjusted fractional seconds.

  1. https://docs.oasis-open.org/cti/stix/v2.0/stix-v2.0-part1-stix-core.html#_Toc496709274
  2. https://docs.oasis-open.org/cti/stix/v2.1/stix-v2.1.html#_xzbicbtscatx
brettforbes commented 5 months ago

Thanks a lot!!!!!