Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code for running moment.js under Java using the Rhino script engine. https://github.com/timrwood/moment/
private static final String MOMENT_JS_FILE = "moment.min.js";
private static JSInvocable newMoment(Long epoch) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(MOMENT_JS_FILE);
Reader reader = new InputStreamReader(is);
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
Object moment;
try {
engine.eval(reader);
if (epoch == null) {
moment = ((Invocable) engine).invokeFunction("moment");
} else {
moment = ((Invocable) engine).invokeFunction("moment", epoch);
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
return new JSInvocable((Invocable) engine, moment);
}
public class JSInvocable {
private final Invocable invocable;
private final Object object;
private JSInvocable(Invocable invocable, Object object) {
this.invocable = invocable;
this.object = object;
}
public String invoke(String method, Object...args) {
if (args == null) { args = new Object[0]; }
try {
return invocable.invokeMethod(object, method, args).toString();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
@rage-shadowman

This comment has been minimized.

Copy link

rage-shadowman commented Dec 29, 2014

Using your code, the following always throws NullPointerException in Java6 for me (works fine in Java7):

JSInvocable invocable = JSInvocable.newMoment( System.currentTimeMillis() );
invocable.invoke( "format", "MMMM Do, YYYY" );

The following works fine in Java6 and Java7:

      InputStream is = Thread.currentThread().getContextClassLoader()
         .getResourceAsStream( "moment.min.js" );
      Reader reader = new InputStreamReader( is );
      ScriptEngineManager manager = new ScriptEngineManager();
      ScriptEngine engine = manager.getEngineByName( "JavaScript" );
      try
      {
         engine.eval( reader );
         return engine.eval( "new moment(" System.currentTimeMillis() + ").format('MMMM Do, YYYY');" ).toString();
      }
      catch( ScriptException e )
      {
         throw new RuntimeException( e );
      }

Of course, you have to escape the format value in case you use quotes so I use:

public static String formatDate( Date date, String format )
{
      InputStream is = Thread.currentThread().getContextClassLoader()
         .getResourceAsStream( "moment.min.js" );
      Reader reader = new InputStreamReader( is );
      ScriptEngineManager manager = new ScriptEngineManager();
      ScriptEngine engine = manager.getEngineByName( "JavaScript" );
      try
      {
         engine.eval( reader );
         format = format.replace( "'", "\\'" );
         String javascript = "new moment(" + date.getTime() + ").format('" + format + "');";
         return evalJavascript( javascript );
      }
      catch( ScriptException e )
      {
         throw new RuntimeException( e );
      }
}

The above has been tested and works with the following also:

MomentJsFormatter.formatDate( new Date(), "MMMM Do, YYYY [at] hh[']mm[\\"]" );
@rage-shadowman

This comment has been minimized.

Copy link

rage-shadowman commented Dec 30, 2014

See this gist for a copy of my MomentJS dateFormat helper for use with jknack's handlebars.java project (including unit tests).

@dwygonow

This comment has been minimized.

Copy link

dwygonow commented Sep 17, 2015

I’m a nubi at this and I am trying to calculate the difference between 2 date values, (ISO8601 format - this is the format that I am getting it in)

var d1 = new Date('2015-07-12T15:06:23');
var d2 = new Date('2015-07-14T16:09:33');

var diff = d2.getTime() - d1.getTime();

return diff;

I am getting NaN.

When I run this;

var d1 = new Date('2015-07-12T15:06:23');
return d1;

I get something like this;

org.mozilla.javascript.NativeDate@2bcf1082

Any help would be greatly appreciated.

Thanx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.