0

This works on Unix, but when I move it over to Windows 7 (machine that script will be run on), using both Ruby 2.1 and 2.2, it fails.

This works (on Windows):

date = Time.new.localtime.to_s
file = File.new("somefile #{1 + 1}", 'a')
file.close

This does not work (on Windows):

date = Time.new.localtime.to_s
file = File.new("somefile #{date}", 'a')
file.close

The resulting error is:

test.rb:2:in 'initialize': Invalid argument @ rb_sysopen - somefile 2015-12-07 11:17:52 -0500 (Errno::EINVAL)
          from test.rb:2:in 'new'
          from test.rb:2:in '<main>'

Any ideas on why this is the case?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
stephen
  • 195
  • 9

2 Answers2

2

Time is a red herring here. The problem is that the colon character (:) is not allowed in a filename on Windows. From MSDN:

Use any character in the current code page for a name, including Unicode characters and characters in the extended character set (128–255), except for the following:

  • The following reserved characters:
    • < (less than)
    • > (greater than)
    • : (colon)
    • " (double quote)
    • / (forward slash)
    • \ (backslash)
    • | (vertical bar or pipe)
    • ? (question mark)
    • * (asterisk)
  • Integer value zero, sometimes referred to as the ASCII NUL character.
  • Characters whose integer representations are in the range from 1 through 31, except for alternate data streams where these characters are allowed. For more information about file streams, see File Streams.
  • Any other character that the target file system does not allow.

Source: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

One solution is to use Time#strftime to output a string without the offending colons, e.g.:

date = Time.new.localtime.strftime("%F %H.%M.%S %z")
file = File.new("somefile #{date}", 'a')
# => #<File:somefile 2015-12-07 11.17.52 -0500>

Alternatively, take a look at this SO answer on the topic of sanitizing a string for use as a filename: How to make a Ruby string safe for a filesystem?

Community
  • 1
  • 1
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
0

Time.new.localtime looks for your systems's ENV['TZ'] variable, which may not be set in Windows 7.

You can follow this link to set ENV['TZ'] on Windows: how to set "TZ" environment variable at system level

Source: http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html#method-i-localtime

Community
  • 1
  • 1
Okomikeruko
  • 1,123
  • 10
  • 22