How do I get the time a message was sent from the Group History?

My application is now working with MultiUserChat. When I join() the chat room, I get the room’'s history as I am supposed to. However, I would like to get the time that the original messages where sent. I note that an Exodus client seems able to get the time the messages in the history were originally sent when connects to a chat room on Messenger, so I must be possible.

Thanks,

Simon.

You need to parse the jabber:x:delay extension from the messages you recieve, assuming the server has added them. (This applies to normal chat messages too).

Try this:

import org.jivesoftware.smack.packet.PacketExtension;
import java.util.Calendar;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException; /** Packet extension for Delayed Delivery jabber:x:delay.
* See <a href="http://www.jabber.org/jeps/jep-0091.html">JEP 91</a>
* for more info.*/
public final class DelayExtension implements PacketExtension{
     
     private static final SimpleDateFormat FORMAT=new SimpleDateFormat("yyyyMMdd''T''hh:mm:ss");
     private static final DateFormat LOCAL_FORMAT=DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);
     private static final DateFormat LOCAL_TIME_FORMAT=DateFormat.getTimeInstance(DateFormat.SHORT);
     
     
     private String from=null;
     private String stamp="";
     private String content=null;
     
     /** Creates an empty DelayExtension.*/
     public DelayExtension(){
          //do nowt
     }
     
     /** Sets the time stamp attribute.*/
     public void setStamp(String stamp){
          if(stamp==null){
               throw new NullPointerException("null stamp passed to setStamp in DelayExtension");
          }
          this.stamp=stamp;
     }
     
     /**Sets the from attribute.*/
     public void setFrom(String from){
          this.from=from;
     }
     
     /** Returns the the x tag content.
     * EG Offline Storage.*/
     public void setContent(String content){
          this.content=content;
     }
     
     /** Returns the from attribute.
     * May return <code>null</code>.*/
     public String getFrom(){
          return from;
     }
     
     /** Returns the the x tag content.
     * EG Offline Storage.
     * May return <code>null</code>.*/
     public String getContent(){
          return content;
     }
     
     /** Returns the time stamp as a string.
     * Format is yyyyMMddThh:mm:ss.*/
     public String getStamp(){
          return stamp;
     }
     
     /** Returns the time stamp as a date object.
     * Returns <code>null</code> if there was a problem parsing the time stamp.*/
     public Date getDate(){
          try{
               Calendar cal = Calendar.getInstance();
               // Convert the UTC time to local time.
               cal.setTime(new Date(FORMAT.parse(stamp).getTime()+cal.getTimeZone().getOffset(cal.getTimeInMillis())));
               return cal.getTime();
          }
          catch (ParseException pe){
               return null;
          }
     }
     
     /** Returns the time stamp as a localised string.
     Returns <code>""</code> if there was a problem parsing the time stamp.*/
     public String getLocalStamp(){
          Date d=getDate();
          if(d==null){
               return "";
          }
          return LOCAL_FORMAT.format(d);
     }
     
     /** Returns the time part of the time stamp as a localised string.
     Returns <code>""</code> if there was a problem parsing the time stamp.*/
     public String getLocalTime(){
          Date d=getDate();
          if(d==null){
               return "";
          }
          return LOCAL_TIME_FORMAT.format(d);
     }
     
     
     // Interface implementation
     
     /** Returns ''x''.*/
     public String getElementName(){
          return "x";
     }
     
     /** Returns ''jabber:x:delay''.*/
     public String getNamespace(){
          return "jabber:x:delay";
     }
          
     public String toXML(){
          StringBuffer buf=new StringBuffer();
          buf.append("<x xmlns=''jabber:x:delay'' ");
          buf.append("stamp=''").append(stamp).append("'' ");
          if(from!=null){
               buf.append("from=''").append(from).append("'' ");
          }
          buf.append(">");
          if(content!=null){
               buf.append(content);
          }
          buf.append("</x>");
          return buf.toString();
     }
}

and this

import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.ProviderManager; /** Packet extension  provider for Delayed Delivery jabber:x:delay.
* See <a href="http://www.jabber.org/jeps/jep-0091.html">JEP 91</a>
* for more info.
* @see DelayExtension*/
public final class DelayExtensionProvider implements PacketExtensionProvider{
           public DelayExtensionProvider(){
          //do nowt
     }
     
     /** Installs the provider.*/
     public static void install(){
          ProviderManager.addExtensionProvider("x","jabber:x:delay",new DelayExtensionProvider());
     }
     
     public PacketExtension parseExtension(org.xmlpull.v1.XmlPullParser parser) throws Exception{
          DelayExtension result=new DelayExtension();
          int c=parser.getAttributeCount();
          String name;
          String value;
          for(int i=0;i<c;i++){
               value=parser.getAttributeValue(i);
               name=parser.getAttributeName(i);
               if(name.equals("stamp")){
                    result.setStamp(value);
               }
               if(name.equals("from")){
                    result.setFrom(value);
               }
          }
          int event=parser.getEventType();
          while (!(event==parser.END_TAG && parser.getName().equals("x"))){
               if(event==parser.TEXT){
                    result.setContent(parser.getText());
               }
               event=parser.next();
          }
          return result;
     }
     
}

At the beginning of your proram call:

DelayExtensionProvider.install();

Then when you recieve a message try:

....
Message msg=..... DelayExtension delay=(DelayExtension) msg.getExtension("x","jabber:x:delay");
if(delay!=null){
     //display time of message
     // for debug:
     System.out.println(delay.getLocalStamp());
}

HTH Pheet

Hey Pheet,

You just beat me with the answer. We are going to add official support for the delay extension for the next release. I was planning on implementing this feature today so I’‘ll let you know when it’'s available as a nightly build.

Regards,

– Gato

Hey guys,

We now have official support for Delayed Delivery (JEP-91). You can find in the next nightly build the new classes.

To get the delay information you need to send #getExtension(“x”,“jabber:x:delay”) to the packet that has the information. This will return an instance of org.jivesoftware.smackx.packet.DelayInformation.

Enjoy,

– Gato

Cool, I was a week ahead

cheers Gato

I’'ve got it working now.

Thanks for the support. I’'ll definitely recomment Jive software to people!

Hey Simon,

Glad to hear that things are working. FYI, if you are using Jive Messenger as your server, you would want to download tomorrow’'s nightly build since it has a fix for offline messages.

Regards,

– Gato

Ok…

the new DelayInformation class returns a Date that represents the UTC timezone.

I’‘m totally stumped on how to conver that Date to a Date in the local timezone. I’‘ve been trying to use Calendar… but once I get a Calendar instance, I can’'t use SimpleDateFormat to format the Date.

How can I convert one Date to another in the current timezone?

Adam

Nevermind, this appears to work:

DelayInformation inf = (DelayInformation)packet.getExtension( "x", "jabber:x:delay" );
Date date = inf.getStamp();
date = new Date( date.getTime() + TimeZone.getDefault().getOffset( date.getTime() ) );