Comments (6)
👍 for this request. However, one clarification: the ...Thh:mm+xx:yy
-notation doesn't support adding time zones, it supports adding time offsets. Those are very different things. There are many zones with the same offset, and every zone can use more than one offset.
For example, U.S. Eastern Time is a time zone that maps different points in time to different time offsets: -4 UTC in the summer, -5 UTC in the winter. But there are plenty of other time zones with the offset -5 UTC (for example, US Central Time is -5 UTC in the summer). The events
API in GCal supports adding either a time zone or a time offset, but you almost always want a zone, not an offset.
from gcalcli.
You can specify a timezone in the --when
option (e.g. --when 2007-09-24T15:30-8:00
), both dateutil and parsedatetime should be able to deal with that. Given we only allow duration and not a specific end time, I'm not sure what the use case is here. Are you wanting an --until
option instead of just --duration
?
from gcalcli.
Hi
When I use --when '2013-03-11T9:30-8:00' --duration 60
, the following event is created:
- Start Time: 18:30
- End Time: 19:30
- Time Zone: +1:00 (my local time zone)
It looks like gcalcli is converting the specified time into my local time zone.
I would expect that the following event was created:
- Start Time: 9:30
- End Time: 10:30
- Time Zone: -8:00 (time zone as specified)
I want to do this because I'm travelling for example to the US and will need to send the event as meeting invite to colleagues. I want that these invites are in the proper time zone.
Also, the --until
parameter would be really nice, especially if it allowed me to specify a time zone as well (potentially a different time zone than in --when
).
Benedikt
from gcalcli.
The following code should enable --until functionality. Once the time zone issue is sorted, --until should make it possible to have events start in one time zone and end in another. It would also be useful to avoid calculating the duration of events where the end time, not duration, is known. The --until argument overrides --duration if both are supplied. The changes are based on version 4.0.4-2 from the Debian 10 repos. If there's interest, I can try to find some time to clean it up and submit the code, but it might be better if someone more familiar with gcalcli and python does that.
diff -r -U0 ./argparsers.py /usr/lib/python3/dist-packages/gcalcli/argparsers.py
--- ./argparsers.py 2019-04-24 16:46:16.000000000 -0700
+++ /usr/lib/python3/dist-packages/gcalcli/argparsers.py 2021-06-20 14:43:32.938992990 -0700
@@ -301,0 +302 @@
+ add.add_argument('--until', default=None, type=str, help='Event end time (overrides --duration)')
diff -r -U0 ./cli.py /usr/lib/python3/dist-packages/gcalcli/cli.py
--- ./cli.py 2019-02-25 23:20:19.000000000 -0800
+++ /usr/lib/python3/dist-packages/gcalcli/cli.py 2021-06-20 14:34:12.832825535 -0700
@@ -70,6 +70,7 @@
- if parsed_args.duration is None:
- if parsed_args.allday:
- prompt = 'Duration (days): '
- else:
- prompt = 'Duration (minutes): '
- parsed_args.duration = get_input(printer, prompt, STR_TO_INT)
+ if parsed_args.until is None:
+ if parsed_args.duration is None:
+ if parsed_args.allday:
+ prompt = 'Duration (days): '
+ else:
+ prompt = 'Duration (minutes): '
+ parsed_args.duration = get_input(printer, prompt, STR_TO_INT)
@@ -181,10 +182,21 @@
- try:
- estart, eend = utils.get_times_from_duration(
- parsed_args.when, parsed_args.duration,
- parsed_args.allday
- )
- except ValueError as exc:
- printer.err_msg(str(exc))
- # Since we actually need a valid start and end time in order to
- # add the event, we cannot proceed.
- raise
+ if parsed_args.until is None:
+ try:
+ estart, eend = utils.get_times_from_duration(
+ parsed_args.when, parsed_args.duration,
+ parsed_args.allday
+ )
+ except ValueError as exc:
+ printer.err_msg(str(exc))
+ # Since we actually need a valid start and end time in order to
+ # add the event, we cannot proceed.
+ raise
+ else:
+ try:
+ estart, eend = utils.get_times_from_until(
+ parsed_args.when, parsed_args.until
+ )
+ except ValueError as exc:
+ printer.err_msg(str(exc))
+ # Since we actually need a valid start and end time in order to
+ # add the event, we cannot proceed.
+ raise
diff -r -U0 ./utils.py /usr/lib/python3/dist-packages/gcalcli/utils.py
--- ./utils.py 2019-02-25 23:20:19.000000000 -0800
+++ /usr/lib/python3/dist-packages/gcalcli/utils.py 2021-06-20 14:36:57.392792278 -0700
@@ -66,0 +67,18 @@
+def get_times_from_until(when, until):
+
+ try:
+ start = get_time_from_str(when)
+ except Exception:
+ raise ValueError('Date and time is invalid: %s\n' % (when))
+
+ try:
+ stop = get_time_from_str(until)
+ except Exception:
+ raise ValueError('Date and time is invalid: %s\n' % (until))
+
+ start = start.isoformat()
+ stop = stop.isoformat()
+
+ return start, stop
+
+
from gcalcli.
Re the time zones, it appears that somewhere along the line, the supplied time zone info. is either getting mangled or dropped, possible at the parser, which may be returning a naive datetime object. Rather than get into that, I added two more parameters, --starttz and --endtz. This works just as well for my use cases. (It would be nice to parse the date input correctly, but for the few of us who need time zone functionality, we're probably happy enough to use the extra parameters.) The information supplied must be in a format the Google Calendar API can understand, but I'd recommend using IDs, like America/New_York, rather than offsets. So, e.g., incorporating --until, from above:
gcalcli ... --when '2021-06-21 1000' --until '2021-06-21 1930' --starttz 'America/New_York' --endtz 'Europe/London'
This diff is against the version as modified above (i.e., --until already included):
diff -U0 -r /tmp/gcalcli_2021-06-20/argparsers.py ./argparsers.py
--- /tmp/gcalcli_2021-06-20/argparsers.py 2021-06-20 14:43:32.000000000 -0700
+++ ./argparsers.py 2021-06-20 16:41:27.000000000 -0700
@@ -302,0 +303,2 @@
+ add.add_argument('--starttz', default=None, type=str, help='Event start time zone (Google Calendar API compatible format)')
+ add.add_argument('--endtz', default=None, type=str, help='Event end time zone (Google Calendar API compatible format)')
diff -U0 -r /tmp/gcalcli_2021-06-20/cli.py ./cli.py
--- /tmp/gcalcli_2021-06-20/cli.py 2021-06-20 14:34:12.000000000 -0700
+++ ./cli.py 2021-06-20 17:54:45.000000000 -0700
@@ -38,0 +39 @@
+from datetime import datetime
@@ -203,0 +205,8 @@
+ # strip time zone info if starttz or endtz supplied, but supply T so Google is happy
+ if parsed_args.starttz is not None:
+ estart_notz = datetime.strptime(estart, "%Y-%m-%dT%H:%M:%S%z").replace(tzinfo=None)
+ estart = str(estart_notz).replace(' ', 'T')
+ if parsed_args.endtz is not None:
+ eend_notz = datetime.strptime(eend, "%Y-%m-%dT%H:%M:%S%z").replace(tzinfo=None)
+ eend = str(eend_notz).replace(' ', 'T')
+
@@ -206 +215,2 @@
- parsed_args.reminders, parsed_args.event_color)
+ parsed_args.reminders, parsed_args.event_color,
+ parsed_args.starttz, parsed_args.endtz)
diff -U0 -r /tmp/gcalcli_2021-06-20/gcal.py ./gcal.py
--- /tmp/gcalcli_2021-06-20/gcal.py 2019-04-24 16:46:16.000000000 -0700
+++ ./gcal.py 2021-06-20 17:05:38.000000000 -0700
@@ -1269 +1269 @@
- def AddEvent(self, title, where, start, end, descr, who, reminders, color):
+ def AddEvent(self, title, where, start, end, descr, who, reminders, color, starttz=None, endtz=None):
@@ -1284,4 +1284,12 @@
- event['start'] = {'dateTime': start,
- 'timeZone': self.cals[0]['timeZone']}
- event['end'] = {'dateTime': end,
- 'timeZone': self.cals[0]['timeZone']}
+ if starttz is None:
+ event['start'] = {'dateTime': start,
+ 'timeZone': self.cals[0]['timeZone']}
+ else:
+ event['start'] = {'dateTime': start,
+ 'timeZone': starttz}
+ if endtz is None:
+ event['end'] = {'dateTime': end,
+ 'timeZone': self.cals[0]['timeZone']}
+ else:
+ event['end'] = {'dateTime': end,
+ 'timeZone': endtz}
from gcalcli.
Again, building on the prior changes, the following allows you to retrieve the actual datetime values as Start: and End:, by supplying "start" and "end" under --details. Should now calculate Length: correctly as well, accounting for time zones. May require the --military parameter. If the time zone is not set correctly in the actual calendar event, "None" is displayed instead of the time zone. Note that the first line of output from search displays time in local time (however that's divined), so ignore that if you're parsing output and use Start: and End: instead.
Sample output from made-up flights (yeah, MAD-DEL is the scenic route):
# gcalcli search 'flight' --details start --details end --military
2021-06-23 16:04 IAD-MAD (AAL 1234; XF4GRK; A321)
Start: 2021-06-23 16:04 (EDT; UTC-0400)
End: 2021-06-23 17:22 (None; UTC+0200)
2021-06-24 06:00 MAD-BOM (MAD 1235; XF4GRK; A346)
Start: 2021-06-24 12:00 (CEST; UTC+0200)
End: 2021-06-25 13:00 (IST; UTC+0530)
diff -U0 -r /tmp/gcalcli_2021-06-21/argparsers.py ./argparsers.py
--- /tmp/gcalcli_2021-06-21/argparsers.py 2021-06-20 16:41:27.000000000 -0700
+++ ./argparsers.py 2021-06-20 21:21:48.000000000 -0700
@@ -11 +11 @@
- 'url', 'attendees', 'email', 'attachments']
+ 'url', 'attendees', 'email', 'attachments', 'start', 'end']
diff -U0 -r /tmp/gcalcli_2021-06-21/gcal.py ./gcal.py
--- /tmp/gcalcli_2021-06-21/gcal.py 2021-06-20 17:05:38.000000000 -0700
+++ ./gcal.py 2021-06-21 15:05:16.000000000 -0700
@@ -10,0 +11 @@
+from pytz import timezone
@@ -758,0 +760,16 @@
+ if self.details.get('start'):
+ if event['start'].get('timeZone'):
+ start_dt_full = parse(event['start']['dateTime']).astimezone(timezone(event['start']['timeZone']))
+ else:
+ start_dt_full = parse(event['start']['dateTime'])
+ xstr = '%s Start: %s (%s; UTC%s)\n' % (details_indent, start_dt_full.strftime("%Y-%m-%d %H:%M"), start_dt_full.tzname(), start_dt_full.strftime("%z"))
+ self.printer.msg(xstr, 'default')
+
+ if self.details.get('end'):
+ if event['start'].get('timeZone'):
+ end_dt_full = parse(event['end']['dateTime']).astimezone(timezone(event['end']['timeZone']))
+ else:
+ end_dt_full = parse(event['end']['dateTime'])
+ xstr = '%s End: %s (%s; UTC%s)\n' % (details_indent, end_dt_full.strftime("%Y-%m-%d %H:%M"), end_dt_full.tzname(), end_dt_full.strftime("%z"))
+ self.printer.msg(xstr, 'default')
+
@@ -760 +777,9 @@
- diff_date_time = (event['e'] - event['s'])
+ if event['start'].get('timeZone'):
+ start_dt_full = parse(event['start']['dateTime']).astimezone(timezone(event['start']['timeZone']))
+ else:
+ start_dt_full = parse(event['start']['dateTime'])
+ if event['start'].get('timeZone'):
+ end_dt_full = parse(event['end']['dateTime']).astimezone(timezone(event['end']['timeZone']))
+ else:
+ end_dt_full = parse(event['end']['dateTime'])
+ diff_date_time = (end_dt_full - start_dt_full)
from gcalcli.
Related Issues (20)
- Can't create an event where a field starts with "@"
- Date Format HOT 1
- when importing a iCS file gcalcli says 'Python vobject module not installed!' even though it is installed HOT 1
- Google Calendar
- Imports are disorganized
- Hourly authentication "The authentication flow has completed."
- Use of summaryOverride HOT 1
- README.md discrepancy
- Importing a .vcs with no events crashes gcalcli
- Formatting and first day of week
- Add option to combine default reminders with custom reminders
- --lineart unicode TypeError: can't concat str to bytes
- App 'gcalcli' is blocked - The out-of-band (OOB) flow has been blocked HOT 8
- DeprecationWarning
- Editing based on unique identifiers?
- Editing an recurring event seems to copy it instead of editing the selected "event instance"
- List Availability
- Access blocked: Authorization Error HOT 1
- HELP: What do I specify? (Documention missing bug)
- HELP!!! GCalCli stopped working! I can only list calendars, and cannot do anything else HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gcalcli.