3

I am writing a manifest.xml file during an Ant build for an OpenCMS project.

I need to be able to pull up a file's create date, and last modified date on a file. (Although the current process is giving each file a timestamp of Wed, 31 Dec 1969 19:00:00 EST anyway -- at least on Windows machines when they run the build.)

Is there a way I can pull up the creation date timestamp of a file in Ant? I'm using standard Ant tasks and Ant-Contrib tasks.

David W.
  • 105,218
  • 39
  • 216
  • 337
  • Here's a similar question with a solution based on Tasksuite Ant Flaka => http://stackoverflow.com/a/5992436/130683 – Rebse Feb 05 '13 at 20:36
  • @Rebse Thanks, I saw that. However, I don't have Flacka installed. I was hoping that someone knows of a way to use ` – David W. Feb 05 '13 at 20:54

4 Answers4

4

I've got this to work.

As Mark O'Connor pointed out, you can't get the file creation time from earlier versions of Java. However, the original Java program that was being used for this task used the lastModified method for both the creation date and the last modified date1. I was fine doing the same thing.

I created a <scriptdef> to do pull the Last Modified date from a file. In Java 1.6 and up, you have access directly to the Rhino JavaScript library, so you no longer need the BeanShell library.

<scriptdef name="file.mdate" language="javascript"> 
    <attribute name="file"/> 
    <attribute name="property"/> 
        file_name = attributes.get("file"); 
        property_to_set = attributes.get("property");

        file = new java.io.File(file_name); 
        file_date = file.lastModified();

        date_format = new java.text.SimpleDateFormat("EEE, dd MMM YYYY HH:mm:ss zzz");
        formated_date = date_format.format(new java.util.Date(file_date));
        project.setNewProperty(property_to_set, formated_date);
</scriptdef> 

Once defined, I can use it as an Ant task:

<file.mdate
    file="${file.name}"
    property="file.modified.date"/>
<echo>The file "${file}" was modified on ${file.modified.date}</echo>
Community
  • 1
  • 1
David W.
  • 105,218
  • 39
  • 216
  • 337
  • You may get the creationtime via systemcommand if OS==Windows, see my answer. – Rebse Feb 06 '13 at 23:20
  • this solution is good, neat and simple. 3rd party library Groovy is not needed. just need to set the property of the file like:. it should work on any system. Particularly, i ran it in my macbook.and its perfect. BIG THANKS! – CodeLikeNoonesBusiness Jun 19 '21 at 05:40
2

It depends on your OS, f.e. Unix doesn't store the file creation time, see details here
Two possible solutions :

Solution 1, works on Windows only with Java >= 6, no addons needed

<project>
  <!-- Works on Windows only, uses the jdk builtin
       rhino javascript engine (since jdk6)
       use dir command without /T:C to get lastmodificationtime
  -->
  <macrodef name="getFileTimes">
    <attribute name="dir" />
    <attribute name="file" />
    <attribute name="setprop" default="@{file}_ctime" />
    <sequential>
      <exec executable="cmd" dir="@{dir}" outputproperty="@{setprop}">
        <arg value="/c" />
        <arg line="dir @{file} /T:C|find ' @{file}'" />
      </exec>
      <script language="javascript">
     tmp = project.getProperty("@{setprop}").split("\\s+") ;
     project.setProperty("@{setprop}", tmp[0] + "/" + tmp[1]) ;
   </script>
    </sequential>
  </macrodef>

  <getFileTimes dir="C:/tmp" file="bookmarks.html" />

  <echo>
  $${bookmarks.html_ctime} => ${bookmarks.html_ctime}
  </echo>
</project>

Solution 2, needs Java 7 and groovy-all-x.x.x.jar (contained in groovy binary release)
Adjust the SimpleDateFormat to your liking.
On Unix filesystems when asking for creationtime you'll get the last modification time.

<project>
  <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>

  <!-- Solution for Java 7, uses the nio package
       needs groovy-all-2.1.0.jar
  -->
  <macrodef name="getFileTimes">
    <attribute name="file"/>
    <attribute name="ctimeprop" default="@{file}_ctime"/>
    <attribute name="mtimeprop" default="@{file}_mtime"/>
    <sequential>
      <groovy>
      import java.nio.file.*
      import java.nio.file.attribute.*
      import java.text.*
      import java.util.date.*

      Path path = Paths.get("@{file}")
      BasicFileAttributeView view = Files.getFileAttributeView(path, BasicFileAttributeView.class)
      BasicFileAttributes attributes = view.readAttributes()
      lastModifiedTime = attributes.lastModifiedTime()
      createTime = attributes.creationTime()
      DateFormat df = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss", Locale.US)
      df.format(new Date(createTime.toMillis()))

      properties.'@{ctimeprop}' = df.format(new Date(createTime.toMillis()))
      properties.'@{mtimeprop}' = df.format(new Date(lastModifiedTime.toMillis()))
     </groovy>
    </sequential>
  </macrodef>

  <getFileTimes file="C:/tmp/bookmarks.html"/>

  <echo>
    $${C:/tmp/bookmarks.html_ctime} => ${C:/tmp/bookmarks.html_ctime}
    $${C:/tmp/bookmarks.html_mtime} => ${C:/tmp/bookmarks.html_mtime}
  </echo>
</project>

I tried also using the builtin javascript engine, but i got errors like :

sun.org.mozilla.javascript.internal.EvaluatorException: missing name after . operator

IMO, for simple things using javascript <script language="javascript"> is sufficient, but if you need to import java packages etc. .. it's a PITA. Groovy simply works.

Community
  • 1
  • 1
Rebse
  • 10,307
  • 2
  • 38
  • 66
  • Actually, the Rhino JavaScript engine built into Java 1.6 and later gives you access to Java objects. I really had no problems with it. I tried pure JavaScript, but the on line documentation is bad. The Java documentation is a lot better. I can get the `cdate` in Unix using `` but that's iffy. Besides our official builds are done on Jenkins which sits on a Unix server. Thanks for the answer. Java 1.7 may be an option. However, we have standardized on Java 1.6 for now. – David W. Feb 07 '13 at 13:19
  • Even though I didn't use this, I still like your answer, so I'm giving you credit. – David W. Feb 07 '13 at 13:22
  • Getting the unix creation time depends upon the used filesystem, f.e. see here http://stackoverflow.com/questions/10171069/file-creation-time-in-unix – Rebse Feb 07 '13 at 21:14
  • It's EOL for Java 6 after beeing extended 2 times (July 2012 -> November 2012 -> February 2013) => https://blogs.oracle.com/henrik/entry/updated_java_6_eol_date – Rebse Feb 07 '13 at 21:21
  • End of life? My Mac is still running JDK 1.6.0_37 as most Macs are. And, my company has finally officially blessed JDK 1.6. Last year, I was working for a company that still used JDK 1.3. I believe Red Hat still has 1.6 as their officially supported release. When you talk about massive business systems, it's hard to get them to change anything. I have 1.7 on my Windows 7 (first Win7 PC I had. The one last year was still XP) and we're testing it out. Maybe we'll move over to 1.7 before 1.8 is EOL'd. – David W. Feb 08 '13 at 01:38
  • Creation time has always been tricky. When is a file a _new_ file? If I use `mv` to rename it, is it a new file, or just a changed name? If I used `mv` to move it? What if I use `cat foo > bar`? Is `bar` a new file? It's probably why the original developers settled on `lastModified` for the _creation time_. – David W. Feb 08 '13 at 01:53
1

Problem is the standard Java File object only supports a method for returning the last modified date:

The problem is addressed in Java 7, using the new NIO classes:

Obviously to take advantage of this in ANT you'd need to write a custom task or embed a script.

Community
  • 1
  • 1
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
0

There was a bug in David W.s answer: it not works on second run, because the attribute is not overwritten on second run.

Change: project.setNewProperty should be project.setProperty

Full code snippet:

<scriptdef name="filedate" language="javascript">
    <attribute name="file"/>
    <attribute name="property"/>
        <![CDATA[
            file_name = attributes.get("file");
            property_to_set = attributes.get("property");

            file = new java.io.File(file_name);
            file_date = file.lastModified();

            date_format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            formated_date = date_format.format(new java.util.Date(file_date));
            project.setProperty(property_to_set, formated_date);
        ]]>
</scriptdef>
Community
  • 1
  • 1
muescha
  • 1,544
  • 2
  • 12
  • 22