nodes: 0, module; 1, function_definition; 2, function_name:normalize_date; 3, parameters; 4, block; 5, identifier:date; 6, expression_statement; 7, if_statement; 8, return_statement; 9, string:'''normalize the specified date to milliseconds since the epoch
  
          If it is a string, it is assumed to be some sort of datetime such as
          "2015-12-27" or "2015-12-27T11:01:20.954". If date is a naive datetime,
          it is assumed to be UTC.
  
          If numeric arguments are beyond 5138-11-16 (100,000,000,000 seconds
          after epoch), they are interpreted as milliseconds since the epoch.
          '''; 10, call; 11, block; 12, elif_clause; 13, elif_clause; 14, else_clause; 15, call; 16, identifier:isinstance; 17, argument_list; 18, pass_statement; 19, comparison_operator:date == "now"; 20, block; 21, call; 22, block; 23, block; 24, attribute; 25, argument_list; 26, identifier:date; 27, identifier:datetime; 28, identifier:date; 29, string:"now"; 30, expression_statement; 31, identifier:isinstance; 32, argument_list; 33, try_statement; 34, expression_statement; 35, raise_statement; 36, identifier:Metadata; 37, identifier:_from_datetime; 38, identifier:date; 39, assignment; 40, identifier:date; 41, tuple; 42, block; 43, except_clause; 44, assignment; 45, call; 46, identifier:date; 47, call; 48, identifier:basestring; 49, identifier:int; 50, identifier:float; 51, identifier:long; 52, expression_statement; 53, if_statement; 54, comment:# For unix timestamps on command line; 55, expression_statement; 56, identifier:ValueError; 57, block; 58, identifier:msg; 59, call; 60, identifier:InvalidDatalakeMetadata; 61, argument_list; 62, attribute; 63, argument_list; 64, assignment; 65, comparison_operator:ts > MAX_TS_SECONDS; 66, comment:# ts was provided in ms; 67, block; 68, assignment; 69, try_statement; 70, attribute; 71, argument_list; 72, identifier:msg; 73, identifier:datetime; 74, identifier:now; 75, attribute; 76, identifier:ts; 77, call; 78, identifier:ts; 79, identifier:MAX_TS_SECONDS; 80, expression_statement; 81, identifier:date; 82, call; 83, block; 84, except_clause; 85, string; 86, identifier:format; 87, identifier:date; 88, identifier:pytz; 89, identifier:UTC; 90, identifier:float; 91, argument_list; 92, assignment; 93, attribute; 94, argument_list; 95, expression_statement; 96, as_pattern; 97, block; 98, string_content:could not parse a date from {!r}; 99, identifier:date; 100, identifier:ts; 101, binary_operator:ts / 1000.0; 102, identifier:datetime; 103, identifier:utcfromtimestamp; 104, call; 105, assignment; 106, identifier:ValueError; 107, as_pattern_target; 108, raise_statement; 109, identifier:ts; 110, float:1000.0; 111, identifier:float; 112, argument_list; 113, identifier:date; 114, call; 115, identifier:e; 116, call; 117, identifier:ts; 118, identifier:dateparse; 119, argument_list; 120, identifier:InvalidDatalakeMetadata; 121, argument_list; 122, identifier:date; 123, call; 124, identifier:str; 125, argument_list; 126, identifier:e
code: def normalize_date(date):
          '''normalize the specified date to milliseconds since the epoch
  
          If it is a string, it is assumed to be some sort of datetime such as
          "2015-12-27" or "2015-12-27T11:01:20.954". If date is a naive datetime,
          it is assumed to be UTC.
  
          If numeric arguments are beyond 5138-11-16 (100,000,000,000 seconds
          after epoch), they are interpreted as milliseconds since the epoch.
          '''
  
          if isinstance(date, datetime):
              pass
          elif date == "now":
              date = datetime.now(pytz.UTC)
          elif isinstance(date, (basestring, int, float, long)):
              try:
                  ts = float(date)
                  if ts > MAX_TS_SECONDS:
                      # ts was provided in ms
                      ts = ts / 1000.0
                  # For unix timestamps on command line
                  date = datetime.utcfromtimestamp(float(ts))
              except ValueError:
                  try:
                      date = dateparse(date)
                  except ValueError as e:
                      raise InvalidDatalakeMetadata(str(e))
          else:
              msg = 'could not parse a date from {!r}'.format(date)
              raise InvalidDatalakeMetadata(msg)
  
          return Metadata._from_datetime(date)