Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
For when you need some :code:datetime
helpers but not a complete replacement for the modules.
Frankly, I love the built in :code:datetime
module. Almost everything I need to do, I can just do with it.
However, a few things tend to creep up datetime and datetime again. Things like:
Here's a short look at what's included.
These allow you to create an unfixed :code:date
or :code:datetime
instance by providing a :code:timedelta
offset and/or factory method.
By default, :code:RelativeDate
uses :code:date.today
and :code:RelativeDateTime
uses :code:datetime.now
as the default factories and both have a default offset of :code:timedelta(0)
:
.. code-block:: python
rd = RelativeDate()
rd.as_date() # date(2016, 7, 24)
rdt = RelativeDateTime()
rd.as_datetime() # datetime(2016, 7, 24, 12, 29)
However, it is also possible to provide other factories as well:
.. code-block:: python
import arrow
rdt = RelativeDateTime(clock=arrow.utcnow)
rdt.as_datetime() # <Arrow [2016-07-24T17:34:58.970460+00:00]>
And as long as the underlying factory produces a :code:date
or :code:datetime
compatible object, everything will just work. By compatible, I mean implements the :code:date
or :code:datetime
interface.
Additionally, if only a static offset from today or now is desired, you can simply provide the offset argument with a :code:timedelta
or dateutil :code:relativedelta
. Note that currently, :code:timedelta
and :code:relativedelta
are not interoperable.
.. code-block:: python
from datetime import timedelta
rd = RelativeDate(offset=timedelta(days=6))
rd.as_date() # date(2016, 7, 30)
:code:RelativeDate
and :code:RelativeDateTime
also allow comparing against regular :code:date
and :code:datetime
instances with the standard operators (==, !=, >, etc). Making these incredibly useful for quickly defining date boundaries that are defined statically (such as in a serializer or ORM model):
.. code-block:: python
from datetime import timedelta, date
rd = RelativeDate(offset=timedelta(days=7))
assert rd > date.today() # always true
Adding and subtracting relative instances actually operate on their offsets, rather than underlying :code:date
or :code:datetime
values.
.. code-block:: python
from datetime import timedelta
rd = RelativeDate(offset=timedelta(days=1))
rd + rd == RelativeDate(offset(timedelta(days=2)))
rd - rd == RelativeDate()
Some alternate constructors are provided where it makes sense, each allows passing an offset but defaults to :code:timedelta()
, provided are:
RelativeDate.today
: the default constructorRelativeDateTime.now
: the default constructor, allows passing a tzinfo object to the factoryRelativeDateTime.utcnow
: factory produces UTC-based datetimes (note: these are NAIVE as it relies on the underlying :code:datetime.utcnow
)RelativeDateTime.today
: the default constructor, does not allow passing a tzinfo objectFor convenience sake there are also truly static constructors:
RelativeDate.fromdate
: hoists a regular date into relative contextRelativeDateTime.fromdatetime
: hoists a regular datetime intoRelativeDateTime.fromdate
: hoists a date into a :code:RelativeDateTime
context, allows passing a tzinfo object, factory looks like :code:datetime.combine(the_date, time(tzinfo=tzinfo))
Any additional static constructors, such as :code:datetime.strptime
, can be derived from these if truly needed.
.. code-block:: python
from datetime import date, time, timedelta
rd = RelativeDate.fromdate(date(2016, 7, 24), offset=timedelta(days=7))
rd.as_date() # date(2016, 7, 31), always
Finally, any functionality not implemented directly in the relative instance is proxied to the underlying :code:date
or :code:datetime
instance.
A range of dates is another tool I find myself needing from time to time, however eager creation can sometimes be very expensive for a large range.
Instead, :code:DateRange
is modeled after the Python 3 :code:range
type, which has fast path lookup for membership, lazy iteration, indexing and slicing (slices return new :code:DateRange
objects)
.. code-block:: python
from datestuff import DateRange
from datetime import date, timedelta
dr = DateRange(start=date(2016, 1, 1), stop=date(2016, 12, 31), step=timedelta(days=7))
date(2016, 1, 8) in dr # true
len(dr) # 53, yes this is correct
list(dr) # [date(2016, 1, 1), date(2016, 1, 8), ...]
dr[1] == date(2016, 1, 8) # True
dr[1:-1:2] == DateRange(date(2016, 1, 8), date(2016, 12, 30), step=timedelta(days=14)) # True
:code:DateRange
also allows creating an open ended range by simply omitting the stop argument. In this case, the only functionality that will not work is using :code:len
and negative indexing/slicing (as there is no end)
Currently, :code:DateRange
does not support :code:relativedelta
as under the hood it uses :code:timedelta.total_seconds
for Python 2 and 3 compatiblity. This could be resolved in the future, but is unlikely. :code:DateRange
is, however, compatible with :code:date
and :code:datetime
like objects and other :code:timedelta
like objects. Interestingly, this would apply to :code:RelativeDate
and :code:RelativeDateTime
as well.
Currently, the only util is :code:within_delta
which is useful for comparing two :code:date
or :code:datetime
(or like) instances within a certain delta.
.. code-block:: python
from datetime import datetime, timedelta
from datestuff import within_delta
d1 = datetime.now()
d2 = datetime.now()
d1 == d2 # false
within_delta(d1, d2, timedelta(seconds=1)) # true
If simple boundary checking is needed, this tool is much more light weight than either :code:DateRange
or :code:RelativeDate
. Sadly, this is another tool that cannot interoperate with :code:relativedelta
as it and :code:timedelta
are unorderable (at least in Python 3).
The MIT License (MIT) Copyright (c) 2016 Alec Nikolas Reiter
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
FAQs
Stuff for dates
We found that datestuff demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.